Jump to content

[Bonnes pratiques] Un service avec une action récurrente


Jorodan

Recommended Posts

Amis HardCodeurs, j'ai besoin de votre avis.

Je commence une liste de Tutoriels "Bonnes pratiques" dans http://wiki.frandroid.com/wiki/D%C3%A9veloppement_Android#Tutoriels_par_cat.C3.A9gories

Ma première idée est le service récurrent. J'ai besoin de votre avis pour écrire un truc bon.

Voici l'implémentation que je propose :

package org.frandroid.tutoriels;


import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class MonService extends Service {

   private LocalBinder binder = new LocalBinder();
   private Handler mHandler = new Handler();
   private long frequency = 60 * 1000 * 2;

   @Override
   public IBinder onBind(Intent intent) {
       return binder;
   }

   @Override
   public void onStart(Intent intent, int startId) {
       super.onStart(intent, startId);
       mHandler.removeCallbacks(mActionRecurrente);
       mHandler.postDelayed(mActionRecurrente, 1);
   }

   @Override
   public void onDestroy() {
       mHandler.removeCallbacks(mActionRecurrente);
       super.onDestroy();
   }

   public class LocalBinder extends Binder {
       MonService getService() {
           return MonService.this;
       }
   }


   private Runnable mActionRecurrente = new Runnable() {
       public void run() {
           Log.d("Action", "Je suis récurrent toutes les 2 minutes.");

           mHandler.postDelayed(this, frequency);
       }
   };
}

Comme vous voyez, j'utilise une retard sur un handler plutôt que par le AlarmManager comme conseillé ici : http://android-developers.blogspot.com/2007/11/stitch-in-time.html

Pensez vous que c'est une "bonne pratique" ???

(ps : je vous invite à faire pleins de tutos comme ca avec moi).

Link to comment
Share on other sites

http://developer.android.com/reference/android/app/AlarmManager.html

Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.

donc ça dépend de ce que tu veux faire :P

si c'est un texte qui clignote, Handler est plus adapté

si tu dois faire une requete http à intervalle régulier, AlarmManager est plus adéquat

Link to comment
Share on other sites

Nouvelle proposition !

Qu'en pensez vous ?

package org.frandroid.tutoriels;


import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class MonService extends Service {

   private LocalBinder binder = new LocalBinder();
   private Handler mHandler = new Handler();
   private long frequency = 60 * 1000 * 2;
   private static boolean started = false;

   @Override
   public IBinder onBind(Intent intent) {
       return binder;
   }

   @Override
   public void onStart(Intent intent, int startId) {
       super.onStart(intent, startId);
       MesActions
   }

   @Override
   public void onDestroy() {
       super.onDestroy();
   }

   public class LocalBinder extends Binder {
       MonService getService() {
           return MonService.this;
       }
   }


   public final static void scheduleService(Context context) {
           if (!started) {
               Intent newIntent = new Intent(context, MonService.class);
               PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, 0);

               AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
               am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, frequency, pendingIntent);
           }
           started = true;
   }

   public final static void unscheduleService(Context context) {
           if (started) {
               Intent newIntent = new Intent(context, MonService.class);
               PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, 0);
                   AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
               am.cancel(pendingIntent);
           }
           started = false;
           }

}

L'intéret vient des deux méthodes statiques pour lancer le service par l'Alarm Manager

Link to comment
Share on other sites

Pour moi, il y a plusieurs choses qui ne "vont pas" :P

Tu utilises PendingIntent.getBroadcast() pour démarrer un service :P (sauf si je me trompe)

Tu oublies de "stop" ton service dans unscheduleService()

Ce qui veut dire que ton service continue de "tourner" :P

Que se passe t-il quand un service est lancé?

L'appli reste "chargée", et le système ne peut pas la dégager.

Si on la tue via un TaskKiller, elle se relance.

Comme tu utilises un AlarmManager, il n'est pas nécessaire que l'application continue de "tourner".

Et le fait que tu utilises un service oblige le système à garder ton appli active.

Mon conseil :

- Garde l'AlarmManager

- Utilise PendingIntent.getBroadcast() pour lancer un broadcast (et non démarrer un service) à intervalle régulier

Par contre, ça oblige à déclarer un BroadcastReceiver dans ton manifest.xml (car ton appli peut ne pas être lancée au moment du Broadcast)

Link to comment
Share on other sites

  • 2 months later...

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...