2012-02-03 17 views
79

Tengo una actividad de Android que necesita atrapar dos difusiones diferentes. Mi enfoque actual es tener una sola BroadcastReceiver dentro de la actividad y ponerse al tanto de las emisiones con él:BroadcastReceiver con múltiples filtros o múltiples BroadcastReceivers?

public class MyActivity extends Activity { 
    private MyActivity.BroadcastListener mBroadcastListener; 
    private boolean mIsActivityPaused = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.mylayout); 

     // Create the broadcast listener and register the filters 
     mIsActivityPaused = false; 
     mBroadcastListener = new BroadcastListener(); 

     IntentFilter filter = new IntentFilter(); 
     filter.addAction(Params.INTENT_REFRESH); 
     filter.addAction(Params.INTENT_UPDATE); 
     registerReceiver(mBroadcastListener, filter); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     mIsActivityPaused = false; 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mIsActivityPaused = true; 
    } 

    @Override 
    protected void onDestroy() { 
     unregisterReceiver(mBroadcastListener); 
     super.onDestroy(); 
    } 

    private void refresh() { 
     // refresh 
    } 

    private void update() { 
     // update 
    } 

    private class BroadcastListener extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(Params.INTENT_REFRESH && !mIsActivityPaused)) { 
       refresh(); 
      } else if (intent.getAction().equals(Params.INTENT_UPDATE)) { 
       update(); 
      } 
     } 
    } 
} 

Quiero ejecutar refresh() sólo si mi actividad es visible en la pantalla, pero quiero coger INTENT_UPDATE y ejecutar update() durante toda la vida de la actividad, independientemente de si la actividad es visible o no.

No encontré ninguna manera de cancelar el registro de solo uno de los dos filtros que registro en onCreate, entonces utilizo un indicador para habilitar o deshabilitar la acción que se ejecutará cuando se intercepte la transmisión INTENT_REFRESH, dependiendo del estado de la actividad.

La pregunta es: ¿es este el enfoque correcto?

O, ¿sería mejor tener dos BroadcastReceivers separados de la siguiente manera:

public class MyActivity extends Activity { 
    private MyActivity.BroadcastListenerRefresh mBroadcastListenerRefresh; 
    private MyActivity.BroadcastListenerUpdate mBroadcastListenerUpdate; 
    private boolean mIsBroadcastListenerRefreshRegistered = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     // Create the broadcast listeners 
     mBroadcastListenerRefresh = new BroadcastListenerRefresh(); 
     mBroadcastListenerUpdate = new BroadcastListenerUpdate(); 

     registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH)); 
     registerReceiver(mBroadcastListenerUpdate, new IntentFilter(Params.INTENT_UPDATE)); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (mBroadcastListenerRefresh != null && !mIsBroadcastListenerRefreshRegistered) { 
      registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH)); 
      mIsBroadcastListenerRefreshRegistered = true; 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (mBroadcastListenerRefresh != null && mIsBroadcastListenerRefreshRegistered) { 
      unregisterReceiver(mBroadcastListenerRefresh); 
      mIsBroadcastListenerRefreshRegistered = false; 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     unregisterReceiver(mBroadcastListenerRefresh); 
     unregisterReceiver(mBroadcastListenerUpdate); 
     super.onDestroy(); 
    } 

    private void refresh() { 
     // refresh 
    } 

    private void update() { 
     // update 
    } 

    private class BroadcastListenerRefresh extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(Params.INTENT_REFRESH)) { 
       refresh(); 
      } 
     } 
    } 

    private class BroadcastListenerUpdate extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(Params.INTENT_UPDATE)) { 
       update(); 
      } 
     } 
    } 
} 

Y cuál tiene mejor rendimiento?

Respuesta

153

lugar, es posible proporcionar dos filtros intención diferentes:

filtro para refresh única

IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH); 

filtro para refresh y actualizar

IntentFilter filterRefreshUpdate = new IntentFilter(); 
filterRefreshUpdate.addAction(Params.INTENT_REFRESH); 
filterRefreshUpdate.addAction(Params.INTENT_UPDATE); 

ahora usted puede cambiar entre los filtros intención mediante el registro y anulando el registro deseado, pero la implementación de su receptor sería la misma

+0

Gracias, esta es una solución mucho mejor y funciona. –

+0

@Waqas ¿Puede proporcionar una implementación de ejemplo de BroadcastReceiver que recibiría múltiples intentos? ¿Es solo una gran declaración de si es así? – gonzobrains

+2

@gonzobrains sí, para propósitos múltiples necesita usar igual cantidad de instrucciones if-else para filtrarlas – waqaslam

23

Para cada acción, cree IntentFilter y regístrelo.

@Override 
protected void onResume() { 

    super.onResume(); 

    BroadcastListener receiver = new BroadcastListener(); 

    // Register the filter for listening broadcast. 
    IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH); 
    IntentFilter filterUpdate = new IntentFilter(Params.INTENT_UPDATE); 

    registerReceiver(receiver, filterRefresh); 
    registerReceiver(receiver, filterUpdate); 
} 



private class BroadcastListener extends BroadcastReceiver { 
    public void onReceive(Context ctx, Intent intent) { 

     if (intent.getAction().equals(Params.INTENT_UPDATE)) { 
      update(); 
     } else if(intent.getAction().equals(Params.INTENT_REFRESH)) { 
      refresh(); 
     } 
    } 

} 
+1

¿No debería preocuparme llamar 'registerReceiver' varias veces e invocar' unregisterReceiver' solo una vez? – mr5

+2

Si llama a registerReceiver varias veces y anula el registro de Receptor solo una vez, la instancia anterior de receptor puede tener fugas. Entonces la instancia se registra y luego usa esa instancia para anular el registro. –

+1

Si se registrara varias veces en la misma acción, entonces diría que debería estar preocupado. – zgulser

Cuestiones relacionadas