Première expérience de service


Introduction à cette section

D'accord, nous avons étudié et étudié l'activité sur Android dans les trois premières sections, je pense que tout le monde en a beaucoup bénéficié ! Au début de cette section, nous continuons à apprendre le deuxième composant d'Android : Service (Service), Bon, sans plus tarder, commençons cette section !


1. Concepts liés aux threads

Avant de commencer à apprendre le service, comprenons d'abord quelques concepts des threads !

1) Concepts associés :

  • Programme : écrit dans une certaine langue afin de compléter un tâche spécifique Un ensemble d'instructions (un ensemble de code statique)
  • processus : programme en cours d'exécution, une planification système et une allocation de ressourcesUnité indépendante, le système d'exploitation va Allouez un espace mémoire pour chaque processus ! Le programme est exécuté dynamiquement en séquence, subissant le chargement et l'exécution du code. Processus complet exécuté !
  • Thread : une unité d'exécution plus petite qu'un processus. Chaque processus peut avoir plusieurs threads. Thread doit être placé dans un processus Pour. exécuter, le thread est géré par le programme , et le processus est planifié par le système  !
  • Compréhension du multi-threading : Exécuter plusieurs instructions en parallèle, et allouer des tranches de temps CPU à chacune selon l'algorithme de planification Les threads sont effectivement exécutés en temps partagé , mais le temps de commutation est très court et l'utilisateur se sent "simultanément" !

2) Cycle de vie du fil :

1.png

3 ) Trois façons de créer un fil de discussion :

  1. Hériter de la classe Thread
  2. Implémenter l'interface Runnable
  3. Implémenter l'interface Callable Si vous utilisez le fil de discussion créé par 2, vous pouvez le démarrer directement comme ceci :
    new Thread(myThread).start();
    Le plus souvent, nous aimons utiliser des classes anonymes, ce qui est écrit comme suit. way:
    new Thread(new Runnable(){
         public void run();
             }).start();

2. La différence entre Service et Thread

En fait, ils ne sont pas étroitement liés, mais de nombreux amis confondent souvent les deux. Compris ! Le thread est un thread, la plus petite unité d'exécution de programme et l'unité de base d'allocation de CPU ! Le service est un composant fourni par Android qui lui permet de rester longtemps en arrière-plan. Le plus courant. L'utilisation est de faire une opération d'interrogation ! Ou vous souhaitez faire quelque chose en arrière-plan, comme télécharger des mises à jour en arrière-plan ! Attention à ne pas confondre ces deux concepts !


3. Diagramme du cycle de vie du service

2.png


4. Analyse du cycle de vie

D'accord, de le cycle de vie dans l'image ci-dessus, nous pouvons savoir qu'il existe deux façons d'utiliser le Service sous Android :

1) StartService() démarre le service
2) BindService() démarre le service
PS : il existe un autre moyen, après avoir démarré le service, de lier Service de commande !


1) Explication détaillée des méthodes associées :

  • onCreate() : rappel immédiatement après la création du service pour la première fois Cette méthode, cette méthode tout au long du cycle de vie ne sera appelé que dans l'ordre !
  • onDestory() : Cette méthode sera rappelée à la fermeture du Service. Cette méthode ne sera rappelée qu'une seule fois !
  • onStartCommand(intent,flag,startId) : La première version est onStart(intent,startId), Lorsque le client appelle la méthode startService(Intent), elle sera rappelée. La méthode StartService peut être appelée plusieurs fois. Mais aucun nouvel objet Service ne sera créé, mais l'objet Service généré précédemment continuera à être réutilisé, mais les rappels continueront. Méthode onStartCommand() !
  • IBinder onOnbind(intent) : Cette méthode est une méthode qui doit être implémentée par Service. Cette méthode renverra un. Objet IBinder, l'application communique avec le composant Service via cet objet !
  • onUnbind(intent) : Cette méthode sera rappelée lorsque tous les clients liés au Service seront déconnectés !

2) StartService démarre le service

Le premier démarrage créera une instance de service, en appelant onCreate() et Méthode onStartCommand(), service en ce moment En entrant dans l'état d'exécution, si StartService est à nouveau appelé pour démarrer le service, aucun nouvel objet Service ne sera créé. Le système réutilisera directement l'objet Service précédemment créé et appellera sa méthode onStartCommand() !
Mais un tel Service n'a pas de lien nécessaire avec son appelant, c'est-à-dire que lorsque l'appelant termine son cycle de vie, Mais tant que stopService n'est pas appelé, le Service continuera à fonctionner
Peu importe le nombre de démarrages du Service, il suffit d'appeler le Service une seule fois pour arrêter le Service


3) BindService démarre le service

Lorsque bindService est utilisé pour lier un service pour la première fois, le système instancie une instance de service et appelez ses méthodes onCreate() et onBind(), puis l'appelant pourra interagir avec le service via IBinder. Si bindService est à nouveau utilisé pour lier le service, le système ne créera pas de nouvelle instance de service, ni onBind(). La méthode sera appelée à nouveau. , transmettra uniquement l'objet IBinder directement aux autres clients ajoutés plus tard !
Si nous dissocions le service, il nous suffit d'appeler unbindService(), auquel moment onUnbind et Les méthodes onDestory seront appelées ! Il s'agit d'une situation client si plusieurs clients sont liés au même service, la situation est la suivante. Lorsqu'un client termine son interaction avec le service, il appelle la méthode unbindService() pour le dissocier. Lorsque tous les clients ne sont plus liés au service, le système détruira le service. (Sauf si le service est également démarré par la méthode startService())
De plus, contrairement à la situation ci-dessus, le Service en mode bindService est lié à l'appelant, ce qui peut être compris comme "Sauterelles sur une corde", ils mourront ensemble. Après bindService, une fois l'appelant détruit, le service sera immédiatement terminé
Analyse du bindService du contexte appelé lors de l'appel du service via BindService bindService ( Intent Service, ServiceConnection conn, int flags)
service : Spécifiez le service à démarrer via cette intention
conn : objet ServiceConnection, l'utilisateur surveille la relation entre le le visiteur et l'état de connexion au Service, La méthode onServiceConnected(ComponentName,IBinder) dans l'objet est rappelée lorsque la connexion réussit ; Si l'hébergeur où se trouve le Service prend fin en raison d'une résiliation anormale ou pour d'autres raisons, le Service sera déconnecté du visiteur. L'appel de la méthode onServiceDisconnected(CompanentName) lors de la connexion, la déconnexion active via la méthode unBindService() n'appellera pas la méthode ci-dessus !
flags : Précisez s'il faut créer automatiquement le Service lors de la liaison (si le Service n'a pas encore été créé), Les paramètres peuvent être 0 (pas de création automatique), BIND_AUTO_CREATE (création automatique)


4) BindService après que StartService démarre le service

Si le service a été démarré par un client via StartService(), alors il sera démarré par d'autres clients Appelez ensuite bindService() pour vous lier au service, puis appelez unbindService() pour dissocier et enfin Si bindService() est appelé pour se lier au Service, les méthodes de cycle de vie déclenchées à ce moment sont les suivantes :
onCreate( )->onStartCommand( )->onBind( )->onUnbind( ) -> onRebind()
PS :Le principe est le suivant : la méthode onUnbind() renvoie true !!! Certains lecteurs peuvent avoir des doutes ici. Service ne devrait-il pas être appelé après avoir appelé unbindService ? méthode onDistory() En fait, c'est parce que ce service est démarré par notre StartService ! , donc si vous appelez la méthode onUnbind() pour dissocier, le Service ne sera pas terminé !
Conclusion : Si nous utilisons bindService pour lier un Service démarré, notez qu'il a déjà été démarré. !!! Le système transmet uniquement l'objet IBinder interne du Service à l'Activité et ne transfère pas le cycle de vie du Service. Il est lié à l'activité, donc lorsque la méthode unBindService() est appelée pour dissocier la liaison, le service ne sera pas détruit !


5. Vérification du cycle de vie

Ensuite, nous écrivons du code pour vérifier le cycle de vie :

1) Vérifiez la séquence d'appel de StartService pour démarrer le Service

Nous personnalisons d'abord un service, réécrivons les méthodes pertinentes et l'utilisateur imprime la vérification sur logcat :

TestService1.java

public class TestService1 extends Service {
private final String TAG = "TestService1";
//Méthodes qui doivent être implémentées
@Override
public IBinder onBind(Intent in tent) {
Log.i(TAG, "la méthode onBind est appelée!");
return null
}

//Appelé lors de la création du service
@Override
public void onCreate() {
Log.i(TAG, "la méthode onCreate est appelée !");
super.onCreate();

// Appelé au démarrage du service
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "la méthode onStartCommand a été appelée !"
return super.onStartCommand (intent, flags ,startId); Été appelé ");
super.onDestroy();
}
}

AndroidManifest.xml termine l'enregistrement du service


<!-- Configurer le composant Service et configurer une action en même temps -->
<service android:name=".TestService1"> >                                                                                                                                Le fichier de mise en page, deux boutons , et enfin l'écriture de MainActivity, appelant respectivement startService( ) et stopService( ) dans l'événement clic du bouton !

public class MainActivity extends Activity {

private Button start
private Button stop ;
@Override
protected void onCreate(Bundle savingInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main) ; (Button) findViewById(R.id.btnstart);
stop = (Button) findViewById(R.id.btnstop);
//Créez le In qui démarre la tente de service et l'attribut Intent
final Intent intent = new Intent();
intent.setAction("com.jay.example.service.TEST_SERVICE1");
//Définir les événements de clic pour deux boutons, respectivement démarrer Arrêter le service
démarrer. setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
           startService(intent);                                         }  
        });  

                stopService(intent);  
                 
            }  
        } );  
    }  
}


Capture d'écran en cours d'exécution :

3.jpg

Cliquez pour démarrer le service :

4.jpg

Je suis rassasié et je n'ai rien à faire, alors je vais en commander quelques autres :

5.jpg

Dernier clic pour arrêter le service :

6.jpg

Analyse des résultats :

À partir des résultats d'exécution ci-dessus, nous pouvons vérifier ce qui est expliqué dans notre diagramme de cycle de vie : Nous avons constaté que la méthode onBind() n'était pas appelée. De plus, cliquer plusieurs fois pour démarrer le service n'appellerait onStartCommand que de manière répétée. Méthode ! Peu importe le nombre de fois que nous démarrons le Service, un stopService arrêtera le Service


2) Vérifiez l'ordre dans lequel BindService démarre le Service :

Avant de commencer à écrire ! code, nous devons d’abord apprendre quelques choses d’abord : La première est la méthode bindService de Context donnée sous la première grande image :

  • Objet ServiceConnection : surveille la connexion entre le visiteur et le service. Si la connexion est réussie, rappel. onServiceConnected(), si une résiliation anormale ou d'autres raisons entraînent la déconnexion du Service du visiteur Une fois connectée, la méthode onServiceDisconnected est rappelée. L'appel de unBindService() n'appellera pas cette méthode
  • Il y a un objet IBinder dans la méthode onServiceConnected, qui peut implémenter le service lié ! communication entre nous ! Lorsque nous développons la classe Service, nous devons implémenter la méthode IBinder onBind() par défaut, qui renvoie L'objet IBinder sera passé au paramètre onServiceConnected dans l'objet ServiceConnection, et nous pourrons Communiquez avec le service via cet IBinder ici !

Résumé :
Étape 1 :Héritez le classeur dans le service personnalisé, implémentez votre propre objet IBinder
Étape 2 :Renvoyer votre propre objet IBinder via la méthode onBind()
Étape 3 :Définissez-en un dans la classe qui lie l'objet Service ServiceConnection, remplacer deux méthodes, onServiceConnected et onDisconnected ! Ensuite, lisez simplement les paramètres transmis par IBinder

Eh bien, l'étape suivante consiste à écrire le code pour vérifier. Ici, nous définissons un service pour le timing, Montrons ensuite l'utilisation de BindService et le processus d'appel de méthode ! Le code est relativement simple et ne sera pas expliqué

TestService2.java :

 !
public class TestService2 extends Service {
private final String TAG = "TestService2";
private int count;
private boolean quit

//Définir la méthode onBinder renvoyée ; object
private MyBinder binder = new MyBinder();
public class MyBinder extends Binder
{
public int getCount()
{ >           return count;                                                     🎜> }  
 
//Méthode qui doit être implémentée, cette méthode sera rappelée lorsque le Service est amené à changer  
 @Override  
 public IBinder onBind(Intent intent) {  
            Log.i(TAG, " la méthode onBind est appelé!");
return binder;
}

//Rappel lorsque le service est créé
@Override
public void onCreate() {
Super. onCreate() ;
Log.i(TAG, "la méthode onCreate est appelée!"
//Créer un fil pour modifier dynamiquement la valeur de count
new Thread()
{ public void run()
                                                                                                                                                                                               {
                                      Thread.sleep(1000);                                                                          count++;
                                                                                                                                                                                                                                                    Log.i(TAG, "méthode onUnbind appelée !" 
return true ;
}

); //Rappel avant la fermeture du service
@Override
public void onDestroy() {
        super.onDestroy( );
this.quit = true
Log.i(TAG, "onDestroyed); méthode a été appelée!");
}
@Override
public void onRe bind(Intent intent ) {
Log.i(TAG, "la méthode onRebind est appelée!");
super .onRebind(intention);
}
}

Enregistrez le composant Service dans AndroidManifest.xml :

<service android:name=".TestService2" android:exported="false"> gt;

MainActivity.java :

public class MainActivity extends Activity {

private Button btnbind;
private Button btncancel;
private Button btnstatus; , lors de la définition d'un objet ServiceConnection
TestService2.MyBinder binder;
private ServiceConnection conn = new ServiceConnection() {

// Cette méthode est rappelée lorsque l'activité se déconnecte du service
        @ Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("------Service DisConnected------");

//This La méthode est rappelée lorsque la connexion entre l'activité et le service réussit
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("------Service). Connecté-- -----");
binder = (TestService2.MyBinder) service;
}
};

@Override
protected void onCre ate(Bundle savingInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnbind = (Button) findViewById(R.id.btnbind); (R.id .btncancel);
btnstatus = (Bouton) findViewById(R.id.btnstatus);        final Intent intent = new Intent();  
        intent.setAction("com.jay.example.service.TEST_SERVICE2");  
        btnbind.setOnClickListener(new OnClickListener() {           
           @Override  
            public void onClick(View v) {  
                //绑定service  
                bindService(intent, conn, Service.BIND_AUTO_CREATE);
            }  
        });  
         
        btncancel.setOnClickListener(new OnClickListener() {  
            @Override   
            public void onClick(View v) {  
                //解除service绑定  
               unbindService(conn);                  
            }  
        } );  
          
        btnstatus.setOnClickListener(new OnClickListener() {  
            @Override   
            public void onClick(View v) {  
                Toast.makeText(getApplicationContext(), "Service的count的值为 : "  
+ binder.getCount(), Toast.LENGTH_SHORT).show(); 🎜>



Cliquez pour verrouiller le service :

7.jpg

Continuer à cliquer sur Verrouiller : aucun changement

8.jpg

Obtenir l'état du Service actuel :

9.jpg

Déliaison :

10.jpg

Si nous nous lions à nouveau Si vous fermez l'activité directement après le réglage, une erreur sera signalée. Ensuite, les méthodes onUnbind et onDestory seront appelées automatiquement !

11.jpg À partir des résultats d'exécution ci-dessus, il est vérifié que dans le diagramme du cycle de vie :

Utilisez BindService pour lier Service, dans l'ordre Appelez les méthodes onCreate(), onBind(), Nous pouvons renvoyer l'objet IBinder personnalisé dans la méthode onBind() puis appeler ; La méthode onServiceConnected() de ServiceConnection peut être obtenue dans cette méthode. Objet IBinder pour effectuer les opérations associées ; il sera automatiquement appelé lorsque le service n'est pas lié. Méthodes onUnbind et onDestroyed, bien sûr, si plusieurs clients sont liés, tous doivent être débloqués Seule la liaison appellera la méthode onDestoryed pour la destruction !

12.jpg