AlarmManager et BroadcastReceiver au lieu de Service – est-ce que c'est mauvais? (Temps libre)

INFORMATIONS DE FOND:

J'ai besoin de mettre à jour certaines données du Web, environ une heure ou deux, même lorsque mon application est fermée. La mise à jour des données elle-même prend environ 40 secondes à 1 minute. Il est ensuite enregistré comme sérialisable dans un fichier. Ce fichier est lu lorsque l'application démarre.

C'EST LA APPROCHE QUE J'AI FAIT POUR LE MOMENT (ne pas utiliser un service)

Utilisez AlarmManager et BroadcastReceiver comme ceci:

private void set_REFRESH_DATA_Alarm(){ mContext = Main.this; alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); broadcast_intent = new Intent(mContext, RepeatingAlarmReceiver_REFRESH_DATA.class); pendingIntent = PendingIntent.getBroadcast(mContext, 0, broadcast_intent, 0); // do a REFRESH every hour, starting for the first time in 30 minutes from now ... Calendar now = Calendar.getInstance(); long triggerAtTime = now.getTimeInMillis()+ (1 * 30 * 60 * 1000); // starts in 30 minutes long repeat_alarm_every = (1 * 60 * 60 * 1000); // repeat every 60 minutes alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, repeat_alarm_every, pendingIntent); } 

My RepeatingAlarmReceiver_REFRESH_DATA.class prend en charge la mise à jour des données à partir du Web:

 public class RepeatingAlarmReceiver_REFRESH_DATA extends BroadcastReceiver { public static Context mContext; ConnectivityManager mConnectivity; @Override public void onReceive(Context context, Intent intent) { mContext = context; // if Network connection is OK (Wifi or Mobile) then Load data ... mConnectivity = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); Log.i("Hub", "mConnectivity.getNetworkInfo(0)=" + mConnectivity.getNetworkInfo(0)); Log.i("Hub", "mConnectivity.getNetworkInfo(1)=" + mConnectivity.getNetworkInfo(1)); if ((mConnectivity.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED) || (mConnectivity.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED)) { Log.i("Hub", "Connectivity OK ..."); Refresh_HIST_DATA(); } else { // else Show Dialog "No network connection" ... Log.i("Hub", "No network connection for the moment... will try again later!"); } } // ========================================================================= private void Refresh_HIST_DATA() { Log.i("Hub", "Refresh_HIST_DATA()... Starting ..."); // etc... } } 

Dans le Manifest, j'ai:

 <receiver android:name="com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA" android:process=":remote" /> 

PROBLÈME:

L'alarme est déclenchée à l'heure et la mise à jour démarre, mais après environ 10 secondes, elle s'arrête (Timeout):

06-25 11: 55: 05.278: WARN / ActivityManager (76): délai de diffusion BroadcastRecord {44bb4348 null} – receiver=android.os.BinderProxy@44bcc670

06-25 11: 55: 05.278: WARN / ActivityManager (76): Récepteur pendant le délai d'attente: ResolveInfo {44bb42c0 com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA p = 0 o = 0 m = 0x0}

06-25 11: 55: 05.278: INFO / Process (76): Signal d'envoi. PID: 819 SIG: 9

06-25 11: 55: 05.298: INFO / ActivityManager (76): Process com.cousinHub.myapp: remote (pid 819) est décédé.

Ps: Curieusement, ce "Timeout" ne se produit pas après environ 10 secondes sur mon HTC Hero (toujours sur Android 1.5 – API Level 4) mais bien sur mon Nexus One (2.1-update1)

Des questions :

  1. Pourquoi ce délai? Un moyen simple d'éviter cela?
  2. Est-ce que j'ai configuré mon BroadcastReceiver correctement dans le manifeste? Dois-je ajouter quelque chose (pour éviter ce délai)?
  3. Devrais-je absolument aller pour un service pour ce genre de fonctionnalité "Actualiser à partir du Web"? (Compte tenu de cet article: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/ ) Si OUI (je devrais passer à un service): tous les bons extraits de code / Tutoriel pour ceci …

Comme toujours, merci de votre aide.

H.

3 Solutions collect form web for “AlarmManager et BroadcastReceiver au lieu de Service – est-ce que c'est mauvais? (Temps libre)”

Pourquoi ce délai?

Vous exécutez le thread d'application principal. Vous ne pouvez pas exécuter le thread d'application principal pendant plus de quelques secondes. De plus, en faisant cela, vous endommagez les performances de l'appareil (parce que vous utilisez une priorité de premier plan ), comme la perte de frame-rate dans les jeux ou les vidéos.

Un moyen simple d'éviter cela?

Ne faites pas de travail significatif (> 100 ms) sur le thread d'application principal. Demandez à votre délégué BroadcastReceiver à un IntentService , peut-être un WakefulIntentService .

Est-ce que j'ai configuré mon BroadcastReceiver correctement dans le manifeste?

Veuillez s'il vous plaît s'il vous plaît, veuillez vous débarrasser de l' android:process=:remote . Vous n'en avez pas besoin, cela ne vous aide pas et les performances dégradantes de l'appareil sont encore plus importantes.

Devrais-je absolument aller pour un service pour ce genre de fonctionnalité "Actualiser à partir du Web"? (Compte tenu de cet article: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/ ) Si OUI (je devrais passer à un service): tous les bons extraits de code / Tutoriel pour ceci …

IMHO, oui. Encore une fois, j'ai écrit cette publication sur le blog. Pour un exemple, voir le projet WakefulIntentService .

Pour plus d'informations, j'ai essayé avec un nouveau fil et fonctionne quand sur Wifi (prend environ 1'30 "pour mettre à jour les données lorsque le téléphone est endormi, il ne se" tue "pas!

 //let's try with a new separate thread ? new Thread(new Runnable() { public void run() { Refresh_HIST_DATA(); } }).start(); 

Mais PAS en mode Mobile (GPRS), car il est tué après environ 10 secondes!

C'est une demi-solution pour le moment et je vais essayer la solution de CommonsWare pour une approche plus propre et plus durable …

Voyons si la nouvelle solution thread fonctionne bien ou c'est juste une chance (j'ai testé seulement pendant quelques heures) …

Si quelqu'un d'autre a une autre suggestion, veuillez l'afficher.

Au lieu du fil. Vous pouvez démarrer un AsyncTask à partir de votre récepteur de diffusion sur la méthode Recive (). Cela ne bloquera pas le thread UI. J'ai même fait moi-même dans mes projets qui est de même nature, c'est-à-dire qu'il doit publier des données toutes les 1 heure.

 public void onReceive(Context context, Intent intent) { // start your Asynctask from here. which will post data in doInBackground() method } 
coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.