AlarmManager et BroadcastReceiver au lieu du service - est-ce mauvais? (Temps libre)
INFO DE BASE:
J'ai besoin de mettre à jour certaines données à partir du web, environ toutes les heures, même si mon application est fermée. La mise à jour de la donnée elle-même prend environ 40 secondes à 1 minute. Il est alors enregistrée comme un Serializable dans un fichier. Ce fichier est lu lors de mon application démarre.
C'EST L'APPROCHE que j'ai PRIS POUR LE MOMENT (pas à l'aide d'un Service)
utiliser le 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);
}
Mon RepeatingAlarmReceiver_REFRESH_DATA.class prend soin de mettre à jour les 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 Manifeste, j'ai :
<receiver android:name="com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA" android:process=":remote" />
PROBLÈME :
L'alarme obtient le feu sur le temps et la mise à jour démarre mais après environ 10 secondes, il s'arrête (Timeout):
06-25 11:55:05.278:
ALERTER/ActivityManager(76): Délai d'attente de
diffusion BroadcastRecord{44bb4348
null} -
récepteur=android.os.BinderProxy@44bcc67006-25 11:55:05.278:
ALERTER/ActivityManager(76): le 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/Processus(76):
L'envoi du signal. PID: 819 SIG: 906-25 11:55:05.298:
INFO/ActivityManager(76): Processus
com.cousinHub.myapp:distance pid (819)
a mort.
ps: curieusement, ce "Délai d'attente" n'est pas le cas après environ 10 secondes sur mon HTC Hero (toujours sur Android 1.5 - API de Niveau 4), mais bien sur mon Nexus One (2.1-update1)
Questions :
- Pourquoi ce délai ? Un moyen simple pour éviter cela ?
- Ai-je configurer mon BroadcastReceiver correctement dans le manifeste ? Dois-je ajouter quelque chose (pour éviter ce délai d'attente) ?
- Dois-je absolument aller pour un Service de ce genre de "Actualiser à partir du Web" de la fonctionnalité ? (en tenant compte de cet article : http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/)
Si OUI (je devrais passer à un service): Tout bon des bouts de code/tutoriel pour cette ...
Comme toujours, merci pour votre aide.
H.
source d'informationauteur Hubert
Vous devez vous connecter pour publier un commentaire.
Vous êtes en cours d'exécution sur le thread principal de l'application. Vous ne pouvez pas exécuter sur le thread principal de l'application pour plus de quelques secondes. Aussi, en faisant cela, vous êtes nuire à la performance de l'appareil (parce que vous êtes en cours d'exécution avec la priorité de premier plan), comme à l'origine de trame taux de perte dans les jeux ou les vidéos.
Ne pas faire d'importants travaux (>100 ms) sur le thread principal de l'application. Votre
BroadcastReceiver
déléguer à unIntentService
peut-être unWakefulIntentService
.Veuillez veuillez veuillez veuillez veuillez vous débarrasser de l'
android:process=:remote
. Vous n'en avez pas besoin, il n'est pas de vous aider, et c'est dégrader les performances de l'appareil encore plus loin.À mon humble avis, oui. Puis de nouveau, j'ai écrit ce billet de blog. Pour un exemple, voir la
WakefulIntentService
projet.Pour information, j'ai essayé avec un nouveau thread et il fonctionne lorsque le Wifi (environ 1'30" pour mettre à jour les données lorsque le téléphone est en veille, il ne peut pas faire 'tué' !
mais PAS quand sur le Mobile (GPRS), comme il se fait tuer après environ 10 secondes!
C'est la moitié d'une solution pour le moment et je vais essayer CommonsWare la solution pour un nettoyant/approche plus durable...
Nous allons voir si le nouveau thread solution fonctionne toujours amende ou était juste de la chance (je l'ai testé seulement pendant quelques heures) ...
Si quelqu'un a une autre suggestion, merci de ne poster.
Au lieu de fil. Vous pouvez démarrer une AsyncTask à partir de votre récepteur de radiodiffusion onRecive() la méthode. Cela ne va pas bloquer le thread d'INTERFACE utilisateur. J'ai moi-même fait même dans mes projets, qui est de même nature, C'est-à-publier des données chaque 1 heure.