Android : Gestion des services

07 avril 2013 rdorigny 1 commentaires

Par service, on entend programme qui travaille en tâche de fond. C'est un terme générique car Android propose plusieurs solutions pour créer un service (Thread, Intention, ...).

Une application Android est généralement conçu de deux entités : la vue et le service. En effet, une application qui ne fait rien, ne sert à rien! Or, c'est le service qui réalise le job. Et transmet l'information pour l'affichage ou traitement.





Android permet la création d'un service, on parle d'un service Android, à ne pas confondre avec le service au sens générique. Une application est généralement constitué d'une activité et d'un service. L'activité est utile pour gérer le service et afficher ses résultats. Nous allons donc voir comment coder cela en Java avec le framework Android.

1) Génération d'un service

Le service est totalement distinct de l'activité, nous verrons plus tard comment rattacher l'un et l'autre. Pour créer un service Android, il faut créer un classe et la faire hériter de la classe android.app.Service.

Dans la classe du service, il est nécessaire de surcharger les méthodes : onCreate(), onStart(), onDestroy() et onBind(). A noter que OnBind() est chargé de faire lien entre le service et l'activité.

Ce qui donne :
package fr.doritique.TestService; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.widget.Toast; public class MyService extends Service { private final IBinder mBinder = new MonServiceBinder(); @Override public IBinder onBind(Intent arg0) { return mBinder; } public void Affiche() { Toast.makeText(MyService.this, "Affichage du service!", Toast.LENGTH_SHORT).show(); } public class MonServiceBinder extends Binder { MyService getService() { return MyService.this; } } }

Attention, il ne faut pas oublier de déclarer le service dans le fichier AndroidManifest.xml. La déclaration du service se fait dans la déclaration de l'application tel que:

Ce qui donne :
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.doritique.gestionserviceactivite" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="fr.doritique.TestService.TestServiceActivite" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="fr.doritique.TestService.MyService" android:enabled="true" /> </application> </manifest>

2) Gestion du service dans l'activité

L'objectif, il ne faut pas l'oublier, est de communiquer entre le service qui travaille en background et une activité qui affichera le résultat du travail réalisé.

Pour démarrer un service, il y a la méthode startService, qui reçoit en paramètre une intention par un objet Intent. Pour arrêter, le service on utilisera la méthode stopService().

Nous avons déclaré dans notre service une méthode onBind() qui fait le lien avec l'activité et retourne un objet IBinder. Ensuite, au niveau de l'activité il faut redéfinir la classe ServiceConnection ainsi que ses deux méthodes onServiceConnected() (qui retourne le lien vers le service) et onServiceDisconnected().

Ensuite, il n'y a plus qu'à appeler la méthode bindService() dans la fonction principale de l'activité pour réaliser la jonction entre le service et l'activité. On lui transmet une intention explicite, un lien vers le service et un flag d'option d'association comme BIND_AUTO_CREATE pour créer le lien vers le service tout au long de sa durée de vie.

Voici un exemple d'une activité qui affiche un message en cliquant sur un bouton, le tout fonctionne grâce au service définit ci-dessus:
package fr.doritique.TestService; import fr.doritique.gestionserviceactivite.R; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.widget.Button; public class TestServiceActivite extends Activity { private MyService myService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Association entre le service et l'activité Intent intentAssociation = new Intent(this, MyService.class); //Test si l'association fonctionne et si oui affiche le bouton d'action if (bindService(intentAssociation, mConnexion, Context.BIND_AUTO_CREATE)) { Button btnService = (Button) findViewById(R.id.MyBtn); btnService.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { myService.Affiche(); } }); } } @Override protected void onDestroy() { super.onDestroy(); unbindService(mConnexion); } private ServiceConnection mConnexion = new ServiceConnection() { // Appelée si connexion établie. Récupère la référence vers le service associé. public void onServiceConnected(ComponentName className, IBinder service) { myService = ((MyService.MonServiceBinder) service).getService(); } // Appelée si connexion est perdue public void onServiceDisconnected(ComponentName className) { myService = null; } }; }

Avec comme vue:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Afficher mon service" android:id="@+id/MyBtn" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button> </LinearLayout>

Et à l'affichage vous aurez:

3)Les Threads

Il est également possible de créer un service en utilisant un Thread comme tâche de fond. Pour cela, il suffit simplement d'utiliser la programmation des processus de JAVA classique. Pour plus d'informations sur ce sujet, vous pouvez vous référencer sur l'article situé ici.

Comment faire pour implémenter un thread dans une application Android?
Il suffit de créer une classe dédiée à nos thread en utilisant l'interface Runnable. Prenons un exemple simpliste pour bien comprendre l'interaction entre l'activité principal d'Android et le la classe Thread. Prenons l'exemple d'un thread qui incrémente un compteur toute les 10 secondes. L'interface de l'activité principale proposera un bouton pour afficher la valeur du compteur.

La classe Compteur génère le Thread chargé du comptage:
package fr.doritique.test_thread; public class Compteur implements Runnable { public int cpt; public void run() { cpt=0; while (true) { try { Thread.sleep(10000); } catch (InterruptedException e) {} cpt++; } } public int getCpt() { return cpt; } }

Ensuite, il suffit de l'implémenter dans notre activité:
package fr.doritique.test_thread; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import android.app.Activity; public class MainActivity extends Activity { Compteur compteur=new Compteur(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Lance le thread Thread t=new Thread(compteur); t.start(); //Affiche la valeur du compteur Button bt =(Button) findViewById(R.id.MyBtn); bt.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Affiche(); } }); } protected void Affiche(){ Toast toast=Toast.makeText(this, String.valueOf(compteur.getCpt()), Toast.LENGTH_LONG); toast.show(); } }

Ce qui affiche:

Conclusion

Voila, vous savez désormais créer un service! Avec cet exemple, seule l'application accède à son service. Le framework permet d'accéder à des services fournis par d'autres applications. Pour cela, il faudra utiliser le langage AIDL (Android Interface Description Language). Nous n'étudierons pas ce concept qui est assez complexe à appréhender, et il peut courant de proposer des services à d'autres applications, mais sachez que cela existe.





rdorigny - 2013-07-09 22:34:44
Salut JB, Difficile à dire, il faudrait que tu me donnes ton code afin de réfléchir à ton PB. @+.

Pseudonyme (obligatoire) :
Adresse mail (obligatoire) :
Site web :

Pour valider votre commentaire, écrivez le texte affiché sur l'image :



© 2017 www.doritique.fr par Robert DORIGNY