AlarmManager y BroadcastReceiver en lugar de servicio – ¿es eso malo? (Se acabó el tiempo)

INFORMACIÓN GENERAL:

Necesito actualizar algunos datos de la web, aproximadamente cada hora, incluso cuando mi aplicación está cerrada. La actualización de los datos en sí toma alrededor de 40 segundos a 1 minuto. A continuación, se guarda como Serializable en un archivo. Este archivo se lee cuando se inicia mi aplicación.

ESTE ES EL ENFOQUE QUE TOMÉ POR EL MOMENTO (no usar un Servicio)

Utilice el AlarmManager y BroadcastReceiver de esta manera:

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 se encarga de actualizar los datos desde la 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... } } 

En el Manifiesto tengo:

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

PROBLEMA:

La alarma se dispara a tiempo y la actualización se inicia, pero después de unos 10 segundos se detiene (tiempo de espera):

06-25 11: 55: 05.278: WARN / ActivityManager (76): Tiempo de espera de difusión BroadcastRecord {44bb4348 null} – receiver=android.os.BinderProxy@44bcc670

06-25 11: 55: 05.278: WARN / ActivityManager (76): Receptor durante el tiempo de espera: ResolveInfo {44bb42c0 com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA p = 0 o = 0 m = 0x0}

06-25 11: 55: 05.278: INFO / Process (76): Señal de envío. PID: 819 SIG: 9

06-25 11: 55: 05.298: INFO / ActivityManager (76): El proceso com.cousinHub.myapp: remote (pid 819) ha muerto.

Ps: extrañamente, este "Timeout" no sucede después de unos 10 segundos en mi HTC Hero (todavía en Android 1.5 – API Nivel 4), pero bien en mi Nexus One (2.1-update1)

Preguntas:

  1. ¿Por qué este tiempo de espera? Cualquier manera fácil de evitar esto?
  2. ¿Configuré mi BroadcastReceiver correctamente en el manifiesto? ¿Necesito agregar algo (para evitar este tiempo de espera)?
  3. ¿Debo ir por un servicio para este tipo de funcionalidad "Actualizar desde Web"? (Considerando este artículo: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/ ) En caso afirmativo (debo cambiar a un servicio): Cualquier buen fragmento de código / Tutorial para esto …

Como siempre, gracias por su ayuda.

MARIDO.

¿Por qué este tiempo de espera?

Se está ejecutando en el hilo principal de la aplicación. No se puede ejecutar en el hilo principal de la aplicación durante más de unos segundos. Además, al hacer esto, está perjudicando el rendimiento del dispositivo (porque está ejecutándose con prioridad de primer plano ), como causar pérdida de velocidad de fotogramas en juegos o videos.

Cualquier manera fácil de evitar esto?

No realice trabajos significativos (> 100ms) en el hilo principal de la aplicación. Haga que su BroadcastReceiver delegue en un IntentService , tal vez un WakefulIntentService .

¿Configuré mi BroadcastReceiver correctamente en el manifiesto?

Por favor, por favor, por favor, por favor, por favor, deshacerse del android:process=:remote . No lo necesita, no le está ayudando, y es degradante el rendimiento del dispositivo aún más.

¿Debo ir por un servicio para este tipo de funcionalidad "Actualizar desde Web"? (Considerando este artículo: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/ ) En caso afirmativo (debo cambiar a un servicio): Cualquier buen fragmento de código / Tutorial para esto …

IMHO, sí. Entonces otra vez, escribí esa entrada del blog. Para ver un ejemplo, consulte el proyecto WakefulIntentService .

Para información, he intentado con un nuevo hilo y funciona cuando en Wifi (tarda unos 1'30 "para actualizar los datos cuando el teléfono está dormido, no se 'mató'!

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

Pero NO cuando en Mobile (GPRS), ya que se muere después de unos 10 segundos!

Es la mitad de una solución por el momento y voy a probar la solución de CommonsWare para un enfoque más limpio y más sostenible …

Vamos a ver si la nueva solución de hilo funciona siempre bien o fue sólo suerte (he probado sólo durante un par de horas) …

Si alguien más tiene otra sugerencia, por favor, publicarlo.

En lugar de hilo. Puede iniciar un AsyncTask desde el método onRecive () del receptor de difusión. Esto no bloqueará el subproceso de interfaz de usuario. Yo mismo he hecho lo mismo en mis proyectos que es de la misma naturaleza, es decir, tiene que publicar datos cada 1 hora.

 public void onReceive(Context context, Intent intent) { // start your Asynctask from here. which will post data in doInBackground() method } 
  • Servicio de Android e hilo de la interfaz de usuario
  • Detectar evento táctil de botones de navegación dentro de un servicio con ventana
  • ¿Cómo reiniciar un servicio después de haber sido asesinado por aplicaciones como "Advanced Task Killer"?
  • ASmack como servicio
  • REST / JSON / XML-RPC / SOAP
  • Detener servicio cuando la aplicación está cerrada
  • Android - bindService más de una vez
  • Mantener viva Servicio de Intención después de que la aplicación es asesinada
  • El servicio no se inició en BOOT COMPLETE
  • Antecedentes Proceso para escanear la ubicación del usuario a intervalos regulares y actualizar la base de datos local incluso cuando la aplicación no está abierta
  • La mejor manera de determinar la aplicación actual (en ejecución) actual (utilizando un servicio?)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.