2011-10-25 21 views
63

Tengo una necesidad de crear un receptor de radiodifusión personalizada en el evento OnCreate de una actividad y, obviamente, tengo que anular el registro del receptor de radiodifusión en caso OnDestroy de la actividadAndroid: cuándo registrarse/cancelar el registro de los receptores de difusión creados en una actividad?

Para mayor claridad este es un fragmento de código que utilizo

public class AnActivity extends Activity { 
    private ResponseReceiver receiver; 

    public class ResponseReceiver extends BroadcastReceiver { 
      public static final String ACTION_RESP = 
       "mypackagename.intent.action.MESSAGE_PROCESSED"; 

      @Override 
      public void onReceive(Context context, Intent intent) { 
// TODO Start a dialogue if message indicates successfully posted to server 
      } 
    } 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP); 
     filter.addCategory(Intent.CATEGORY_DEFAULT); 
     receiver = new ResponseReceiver(); 
     registerReceiver(receiver, filter); 
    } 

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

he leído que onPause/onResume y onStart/OnStop eventos para la actividad también debe registrar y anular el registro del receptor de radiodifusión.

Estoy realmente queriendo entender lo que se considera la mejor práctica para esto y por qué.

Respuesta

75

Debe registrar y anular el registro de sus receptores onStart() y onStop().

El único motivo por el que se registraría una actividad BroadcastReceiver s es utilizar los eventos de alguna manera en la actividad actual para informar al usuario de un evento. Si se ha llamado al onStop(), entonces el Activity ya no está en primer plano y, por lo tanto, no puede actualizar al usuario.

Si desea recibir eventos de transmisión en segundo plano, debe considerar utilizar un servicio como se indica en here.

Como dice Konstantin, no se garantiza que se llame al onDestroy(), y puede continuar recibiendo transmisiones durante mucho tiempo, cuando el Activity ya no está abierto.

+3

¿Está sugiriendo que me registre en el registro INSTEAD de onCreate o también? ¿Siempre se llama a OnResume cuando se crea una actividad? – jamesc

+7

Debe registrarse onResume yes, onResume() siempre se invoca en la actividad que se muestra (es el último método llamado antes de que su actividad aparezca (http://developer.android.com/reference/android/app/Activity.html) si solo se registra en Crear() y anular el registro en Pausa(), la próxima vez que la actividad pase a primer plano, no se volverá a llamar a onCreate() y luego no volverá a registrar el receptor. Y sí, quiero decir EN LUGAR de, no lo haga onCreate(). – SnowyTracks

+1

@SnowyTracks: ¿puede comentar por qué es preferible realizar llamadas de registro de BroadcastReceiver en Reanudar/Activar en lugar de enIniciar/detener? Si observa la guía del desarrollador de servicios enlazados, encontré [esto] (http : //developer.android.com/guide/components/bound-services.html#Binding). Hacia el final de esta sección, se recomienda realizar el enlace/desvinculación del servicio en onStart/onStop en lugar de onResume/onPause (para el rendimiento razones). I pregunto si esto también se aplica a BroadcastReceivers? Gracias por adelantado. –

18

Como no se garantiza el llamado onDestroy(), deberá usar onPause() para anular el registro. Considera el ciclo de vida de tu receptor de emisión: ¿Necesitas que esté activo, solo cuando tu actividad está en primer plano? Luego use onResume()/onPause()

4

Android puede matar su aplicación al omitir el método onStop(). La mejor manera de resolver esa situación es registrar BroadcastReceiver en el método onResume() y anular el registro en onPause().

+0

Estoy haciendo esto también. Tuve problemas con 'onStop()' aswell –

4

La documentación Android no prescribe un solo lugar para registrar/anular el registro receptores de radiodifusión, pero it mentions tanto onStart()/onStop() y onResume()/onPause() como posibilidades.

El factor más importante a la hora de tomar esta decisión es, ¿cuándo necesita su receptor poder hacer su trabajo? Esto determinará cuándo registrarse y cancelar el registro.

  • ¿Necesita el receptor hacer algo acerca de la transmisión solo cuando la actividad está enfocada? Si es así, puede registrar/anular el registro en onPause()/onReceive(). (También puede utilizar un tiempo de vida más largo, como onStart()/onStop(), pero entonces usted debe comprobar durante el receptor de onReceive() si la actividad está enfocada.)

  • Qué tiene que hacer algo cuando visible, el receptor, incluso si doesn ¿Tiene enfoque (por ejemplo, cuando se muestra un cuadro de diálogo)? Si es así, use onStart()/onStop() (o una vida útil más larga, pero una vez más, el receptor onReceive() debe verificar si la actividad está visible).

  • ¿El receptor necesita saber acerca de la transmisión incluso cuando la actividad no es visible? Por ejemplo, ¿necesita recordar que algo ha sucedido, de modo que cuando la actividad se vuelva visible, puede reflejar el estado de cosas resultante? Luego debe usar onCreate()/onDestroy() para registrar/anular el registro. (Tenga en cuenta que hay otras maneras de implementar este tipo de funcionalidad.)

Si se registra en onStart(), no también registrarlos en onResume(), porque eso sería redundante: onResume() nunca es llamado sin ser llamado onStart() primero.

También hay que tener en cuenta que lo mejor es keep onPause() as light as possible:

onPause() de ejecución es muy breve, y no necesariamente permitirse tiempo suficiente para llevar a cabo las operaciones de salvar. Por esta razón, debe no usar onPause() para guardar aplicaciones o datos de usuario, realizar llamadas a la red o ejecutar transacciones de base de datos; Tal trabajo puede no completar antes de que el método se complete. En su lugar, debe realizar operaciones de apagado de cargas pesadas durante onStop().

Es cierto que onDestroy() es not guaranteed to be called si el sistema mata a su proceso con el fin de ahorrar memoria. Sin embargo, si el proceso se cancela, el proceso no recibirá transmisiones de todos modos. En ese caso, ¿es realmente necesario anular el registro de los receptores de difusión?

+0

Gracias por su respuesta a mi pregunta, pero su respuesta es confusa y no estrictamente precisa Usted dice 'Si se registra en onStart(), tampoco los registra en onPause(), porque eso sería redundante: onPause() nunca se invoca sin que onStart() se llame primero. 'es simplemente ilógico y confuso, especialmente cuando la respuesta aceptada es perfectamente precisa. – jamesc

+0

@jamesc: Oops, quise decir onResume en lugar de onPause. Tienes razón, eso es un poco confuso. Corregido ahora. En cuanto a la respuesta aceptada, lo he comentado. Creo que esta respuesta agrega información significativa y relevante que la aceptada no ofrece. – LarsH

Cuestiones relacionadas