Utilisation des "Service" et du "Binding"

  • Réponses :1
  • Sticky
julien
  • Posts de Forum 8

18 juin 2013 à 22:27:26 via site

J’espère que ce tutoriel pourra en aider quelques-uns, comme j'arrive sur le forum j'ai voulu en rédiger un. Il est tiré de mon blog personnel dont le lien est précisé à la fin.

J’ai récemment réalisé une application dans le but d’apprendre à utiliser les Services sous Android.

Maintenant je vous propose un article présentant la manière dont j’ai utilisé le service dans mon application. Il s’agit ici d’un service Interne.

1/ Contexte

La mise en place d’un service pour cette application est utile pour deux principales raisons.

- La première réside dans le fait qu’au démarrage du téléphone, l’application Android (activité) ne se lance pas, mais il peut être utilise de vouloir démarrer tout de même une tache sans le notifier à l'utilisateur.

- La seconde est qu'avec les services, l'utilisateur a la possibilité de lancer une application, de démarrer un traitement, de fermer l'application (l'activité). Une fois celle-ci fermée, le traitement en tache de fond peut continuer.

2/ L’architecture du projet

Pour mettre en place un service sous Android, nous aurons besoin de 3 classes.

- Une constituant le service en lui même.

- Une autre permettant de mettre en lien l’Activité avec le Service (Binding)

- Une dernière, qui est l’Activité avec laquelle nous souhaitons paramétrer et utiliser le Service.

Voici un schéma de l’architecture des classes mise en oeuvre:



3/ Le Service

Dans les prochaines sections, pas besoin de description, les commentaires sur le code explique précisément le fonctionnement.

1package com.service;
2/**
3* @author: julien dumortier
4*
5* @version: 1
6*
7* classe: MyService
8*
9* 17 janv. 2013
10*/
11import com.service.BackgroundServiceBinder.IMyServiceMethod;
12import android.app.Service;
13import android.content.Intent;
14import android.os.IBinder;
15
16public class MyService extends Service implements IMyServiceMethod {
17 private IBinder mBinder; //l'instance du binder correspondant à notre service
18 private String mData;
19
20 public void onCreate() {
21 //au démarrage du service, on créé le binder en envoyant le service
22 mBinder = new BackgroundServiceBinder(this);
23 }
24 public IBinder onBind(Intent arg0) {
25 return mBinder;
26 }
27 public String getDataFromService() {
28 return mData;
29 }
30 public void setDataToService(String data) {
31 mData = data;
32 }
33}

4/ Le Binder

1//Binder implémente IBinder
2public class BackgroundServiceBinder extends Binder {
3 private IMyServiceMethod mService;
4 //on recoit l'instance du service
5 public BackgroundServiceBinder(IMyServiceMethod service) {
6 super();
7 mService = service;
8}
9/** @return l'instance du service */
10public IMyServiceMethod getService(){
11 return mService;
12}
13/** les méthodes de cette interface seront accessibles par l'activité */
14public interface IMyServiceMethod {
15 public String getDataFromService();
16 public void setDataToService(String data);
17}

5/ L’Activité

1public class MyActivity extends Activity {
2 //code de l'élevenement indiquant que l'activité est bindé avec le service
3 private static final int ON_BIND = 1;
4 // ServiceConnection permet de gérer l'état du lien entre l'activité et le service.
5 private ServiceConnection mServiceConnection;
6 private IMyServiceMethod mService;
7 private Handler mHandler;
8
9 public void onCreate(Bundle savedInstanceState) {
10 super.onCreate(savedInstanceState);
11 mHandler = new Handler() {
12 public void handleMessage(Message msg) {
13 if(msg.what == ON_BIND) {
14 //on édite les données du service (une fois l'évenement ON_BIND lancé)
15 mService.setDataToService("Voici les données !");
16 //maintenant on peut récupérer les données.
17 showDataFromService();
18 }
19 }
20 };
21 setContentView(R.layout.activity);
22 bindToService();
23 }
24 public void onDestroy() {
25 super.onDestroy();
26 //on supprimer le binding entre l'activité et le service.
27 if(mServiceConnection!=null)
28 unbindService(mServiceConnection);
29 }
30 private void bindToService() {
31 mServiceConnection = new ServiceConnection() {
32 public void onServiceDisconnected(ComponentName name) {}
33 public void onServiceConnected(ComponentName arg0, IBinder binder) {
34 //on récupère l'instance du service dans l'activité
35 mService = ((BackgroundServiceBinder)binder).getService();
36 //on genère l'évènement indiquant qu'on est "bindé"
37 mHandler.sendEmptyMessage(ON_BIND);
38 }
39 };
40 //démarre le service si il n'est pas démarré
41 //Le binding du service est configuré avec "BIND_AUTO_CREATE" ce qui normalement
42 //démarre le service si il n'est pas démarrer, la différence ici est que le fait de
43 //démarrer le service par "startService" fait que si l'activité est détruite, le service
44 //reste en vie (obligatoire pour l'application AlarmIngressStyle)
45 startService(new Intent(this, MyService.class));
46 Intent intent = new Intent(this, MyService.class);
47 //lance le binding du service
48 bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
49 }
50 private void showDataFromService() {
51 //récupération des données depuis le service
52 String data = mService.getDataFromService();
53 //affichage d'un toast
54 Toast.makeText(this, data, Toast.LENGTH_LONG).show();
55 }
56}

6/ Le Manifest

1<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
2
3<application
4 android:allowBackup="true"
5 android:icon="@drawable/ic_launcher"
6 android:label="@string/app_name"
7 android:theme="@style/AppTheme" >
8
9 <!-- déclaration de l'activité -->
10 <activity
11 android:name="com.service.MyActivity"
12 android:label="@string/app_name" >
13 <intent-filter>
14 <action android:name="android.intent.action.MAIN" />
15 <category android:name="android.intent.category.LAUNCHER" />
16 </intent-filter>
17 </activity>
18 <!-- déclaration du service -->
19 <service android:name="com.service.MyService"
20 android:enabled="true"
21 android:exported="false"/>
22 <!-- décaration du BroadcastReceiver -->
23 <receiver android:name="com.service.OnBootReceiver" android:enabled="true"
24 android:exported="false" android:label="OnBootReceiver">
25 <intent-filter>
26 <action android:name="android.intent.action.BOOT_COMPLETED" />
27 </intent-filter>
28 </receiver>
29</application>

7/ Broadcast receiver

Vous avez peut être remarquer dans le manifest, la déclaration du receiver. Ceci permet d’appeler la classe OnBootReceiver au démarrage du téléphone.

Ci-dessous, les sources de cette classe afin de pouvoir démarrer le Service au Boot de téléphone:

1public class OnBootReceiver extends BroadcastReceiver {
2 public static final String TAG = "Mon Service";
3
4 public void onReceive(Context context, Intent intent) {
5 //message de log
6 Log.d(TAG, "Demarrage du service ->->-> ");
7 //démarrage du service via un intent
8 context.startService(new Intent().setComponent(new ComponentName(
9 context.getPackageName(), MyService.class.getName())));
10 }
11}

Avec tout ces éléments vous êtes maintenant en mesure de créer un service pour exécuter du code en taches de fond. Pour ma part, mon service est chargé de plusieurs chose:

- Vérifier périodiquement une condition.

- Gérer l’affichage d'une notification si la condition est respectée.

J'espere que ce tutoriel pourra en aider quelque-un, comme j'arrive sur le forum j'ai voulut en rédiger un. Voici le lien vers le tutoriel original sur mon blog julien-dumortier.fr/service-et-binding-sous-android/

Je suis ouvert à toutes remarque, critiques, conseils, ... ! (est-il possible d'activer la coloration syntaxique pour le code ?)

Merci !

— Modifié le 18 juin 2013 à 22:29:21

Répondre
Ivan Petrovic
  • Posts de Forum 324

30 mai 2016 à 13:49:38 via site

merci pour ton partage

Répondre