Come usare LocalBroadcastManager?


452

Come utilizzare / individuare LocalBroadcastManagercome descritto nei documenti di Google e nel documento di trasmissione del servizio ?

Ho provato a cercarlo su Google, ma non esiste un codice per iniziare?

I documenti dicono che dovrei usarlo se voglio fare una trasmissione interna con nel processo della mia app, ma non so dove cercarlo.

Qualche aiuto / commento?

Aggiornamento : so come usare le trasmissioni ma non so come renderle LocalBroadcastManagerdisponibili nel mio progetto.


Waqas, hai registrato il ricevitore in manifest. Se sì, per favore fatemi sapere come?
Mudassir,

2
Non penso che tu debba registrare il ricevitore per tali trasmissioni in manifest, perché se lo fai, allora quel ricevitore ascolterà anche le trasmissioni globali.
waqaslam,

2
Vero. Quindi questo significa che devo farlo nel codice come indicato nella risposta di seguito; LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name"));
Mudassir,

2
LocalBroadcastManagerè stato deprecato. Ho sostituito il mio con la libreria EventBus che è molto più carina, imo.
Kris B

Risposte:


862

Risponderò comunque. Nel caso in cui qualcuno ne abbia bisogno.

ReceiverActivity.java

Un'attività che controlla le notifiche per l'evento denominato "custom-event-name".

@Override
public void onCreate(Bundle savedInstanceState) {

  ...

  // Register to receive messages.
  // We are registering an observer (mMessageReceiver) to receive Intents
  // with actions named "custom-event-name".
  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
      new IntentFilter("custom-event-name"));
}

// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    // Get extra data included in the Intent
    String message = intent.getStringExtra("message");
    Log.d("receiver", "Got message: " + message);
  }
};

@Override
protected void onDestroy() {
  // Unregister since the activity is about to be closed.
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
  super.onDestroy();
}

SenderActivity.java

La seconda attività che invia / trasmette notifiche.

@Override
public void onCreate(Bundle savedInstanceState) {

  ...

  // Every time a button is clicked, we want to broadcast a notification.
  findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      sendMessage();
    }
  });
}

// Send an Intent with an action named "custom-event-name". The Intent sent should 
// be received by the ReceiverActivity.
private void sendMessage() {
  Log.d("sender", "Broadcasting message");
  Intent intent = new Intent("custom-event-name");
  // You can also include some extra data.
  intent.putExtra("message", "This is my message!");
  LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

Con il codice sopra, ogni volta che si R.id.button_sendfa clic sul pulsante , un Intento viene trasmesso e ricevuto da mMessageReceiverin ReceiverActivity.

L'output di debug dovrebbe essere simile al seguente:

01-16 10:35:42.413: D/sender(356): Broadcasting message
01-16 10:35:42.421: D/receiver(356): Got message: This is my message! 

7
Grazie. ha funzionato già. ma il problema che ho riscontrato è stato quello di entrare in possesso della classe LocalBroadcastManager. Dal momento che è una classe di pacchetti di supporto, quindi non sono stato in grado di usarlo nel mio pacchetto ordinario fino a quando non ho aggiunto la libreria di compatibilità da Strumenti Android. Una volta aggiunto, tutto è andato bene. comunque, grazie per la risposta
waqaslam,

195
si prega di notare che onDestroy()non è garantito che venga chiamato !!! Devi usare onPause()(perché solo onPause()è garantito) e onResume()(perché è la partita per onPause())
18446744073709551615

5
Gente, notate cosa dicono ora i documenti di google su un'attività dopo onPause (): Killable = Pre-HONEYCOMB A partire da Honeycomb, un'applicazione non è nello stato killable fino a quando non viene restituito onStop ().
18446744073709551615

59
onDestroy()non è un problema. Il caso in cui non viene chiamato è quando l'app viene uccisa e non importa se non si annulla la registrazione in quel caso poiché nemmeno l'elenco dei ricevitori registrati sopravvive.
zapl

4
@Selvin Spero che tu sia consapevole che puoi fare in modo che BroadcastReciever faccia debolmente riferimento all'attività di ricezione e annullarne la registrazione se è rimasto orfano. Non è necessario annullare la registrazione in onPause, onDestroy va bene finché non si utilizza BroadcastReceiver per mantenere l'attività nella RAM. Il tuo esempio mostra una cattiva pratica con una classe interna che perde la sua classe esterna, non è unica per BroadcastReceiver ed è qualcosa che i programmatori devono sempre evitare. Per quanto riguarda la modifica della GUI, è possibile memorizzare uno stato per quando l'attività viene ripresa, non è necessario modificare la GUI.
JohanShogun,

133

Preferirei rispondere in modo completo.

  1. LocalbroadcastManager incluso in Android 3.0 e versioni successive, quindi è necessario utilizzare la libreria di supporto v4 per le versioni precedenti. vedi le istruzioni qui

  2. Creare un ricevitore di trasmissione:

    private BroadcastReceiver onNotice= new BroadcastReceiver() {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            // intent can contain anydata
            Log.d("sohail","onReceive called");
            tv.setText("Broadcast received !");
    
        }
    };
  3. Registra il tuo ricevitore su onResume di attività come:

    protected void onResume() {
            super.onResume();
    
            IntentFilter iff= new IntentFilter(MyIntentService.ACTION);
            LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, iff);
        }
    
    //MyIntentService.ACTION is just a public static string defined in MyIntentService.
  4. unRegistra ricevitore in onPause:

    protected void onPause() {
      super.onPause();
      LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
    }
  5. Ora, ogni volta che un broadcast locale viene inviato dall'attività o dal servizio delle applicazioni, onReceive di onNotice verrà chiamato :).

Modifica: puoi leggere il tutorial completo qui LocalBroadcastManager: passaggio dei messaggi dell'applicazione Intra


15
+1. se il tuo ricevitore di trasmissione si trova in un frammento, registralo utilizzando LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onNotice);e annulla la registrazione utilizzandoLocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onNotice);
PeteH

3
Sei sicuro che LocalBroadcastManager sia incluso in Android 3.0 e versioni successive? Non riesco a trovarlo da nessuna parte tranne il supporto lib
mente

5
stranamente, LBM è incluso solo nella libreria di supporto.
Jeffrey Blattman,

1
super.onPause () dovrebbe essere l'ultima istruzione quando si sovrascrive il metodo onPause. Annulla la registrazione prima di super.onPausa per evitare bug imprevedibili
Thupten

2
Credo che potresti voler spostare il tuo ciclo di vita onStopperché in Android API 24+ con "Multi-Window / Split-View" (abilitato per impostazione predefinita su API 26+ affaicr), l'attività con cui non interagisci è nello stato di pausa. Fonte: developer.android.com/guide/topics/ui/…
Martin Marconcini,

45

Alla fine della ricezione:

  • Primo registro LocalBroadcast Receiver
  • Quindi gestire i dati degli intenti in arrivo in onReceive.

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
          lbm.registerReceiver(receiver, new IntentFilter("filter_string"));
      }
    
      public BroadcastReceiver receiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              if (intent != null) {
                  String str = intent.getStringExtra("key");
                  // get all your data from intent and do what you want 
              }
          }
      };

Alla fine dell'invio:

   Intent intent = new Intent("filter_string");
   intent.putExtra("key", "My Data");
   // put your all data using put extra 

   LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

Nel mio caso solo quando ho impostato l'azione intenzionalmente quando si invia la trasmissione funziona altrimenti il ​​metodo onReceive () non ha mai chiamato ...
Akash Bisariya,

27

In Eclipse, alla fine ho dovuto aggiungere la libreria di compatibilità / supporto facendo clic con il tasto destro sul mio progetto e selezionando:

Android Tools -> Add Support Library

Una volta aggiunto, sono stato in grado di utilizzare la LocalBroadcastManagerclasse nel mio codice.


Libreria di compatibilità Android


12

Come modificare la trasmissione globale in LocalBroadcast

1) Crea istanza

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);

2) Per la registrazione di BroadcastReceiver

Sostituire

registerReceiver(new YourReceiver(),new IntentFilter("YourAction"));

Con

localBroadcastManager.registerReceiver(new YourReceiver(),new IntentFilter("YourAction"));

3) Per l'invio di messaggi broadcast

Sostituire

sendBroadcast(intent);

Con

localBroadcastManager.sendBroadcast(intent);

4) Per annullare la registrazione del messaggio broadcast

Sostituire

unregisterReceiver(mybroadcast);

Con

localBroadcastManager.unregisterReceiver(mybroadcast);

Come posso registrare più IntentFilter ??
Parikshit Chalke,

@ParikshitChalke: link
XMAN

12

localbroadcastmanager è deprecato, utilizzare invece le implementazioni del modello osservabile.

androidx.localbroadcastmanager è obsoleto nella versione 1.1.0

Motivo

LocalBroadcastManagerè un bus di eventi a livello di applicazione e comprende le violazioni dei livelli nella tua app; qualsiasi componente può ascoltare eventi da qualsiasi altro componente. Eredita inutili limitazioni del caso d'uso del sistema BroadcastManager; gli sviluppatori devono usare Intent anche se gli oggetti vivono in un solo processo e non lo abbandonano mai. Per lo stesso motivo, non segue BroadcastManager per quanto riguarda le funzionalità.

Questi si sommano a un'esperienza di sviluppo confusa.

Sostituzione

È possibile sostituire l'utilizzo di LocalBroadcastManagercon altre implementazioni del modello osservabile. A seconda del caso d'uso, potrebbero essere disponibili opzioni adeguateLiveData o flussi reattivi.

Vantaggio di LiveData

Puoi estendere un LiveDataoggetto usando il modello singleton per avvolgere i servizi di sistema in modo che possano essere condivisi nella tua app. L' LiveDataoggetto si connette al servizio di sistema una volta, quindi qualsiasi osservatore che necessita della risorsa può semplicemente guardare l' LiveDataoggetto.

 public class MyFragment extends Fragment {
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        LiveData<BigDecimal> myPriceListener = ...;
        myPriceListener.observe(this, price -> {
            // Update the UI.
        });
    }
}

Il observe()metodo passa il frammento, che è un'istanza di LifecycleOwner, come primo argomento. Ciò indica che questo osservatore è legato Lifecycleall'oggetto associato al proprietario, nel senso che:

  • Se l'oggetto Ciclo di vita non è in uno stato attivo, l'osservatore non viene chiamato anche se il valore cambia.

  • Dopo la distruzione dell'oggetto Ciclo di vita, l'osservatore viene rimosso automaticamente

Il fatto che gli LiveDataoggetti siano consapevoli del ciclo di vita significa che è possibile condividerli tra più attività, frammenti e servizi.


1
hai ragione a perdere contesti in tutto il mondo, ma vorrei sapere quale sarebbe un sostituto adatto quando voglio comunicare da un servizio in primo piano che è in esecuzione anche senza un'attività, ma quando arriva l'attività, devono comunicare?
ateebahmed il

1
Crea una classe singleton con un oggetto LiveData e pubblica i tuoi dati dal servizio. Una volta avviata l'attività, l'attività può facilmente osservare LiveData senza alcun danno. ad es .: MyServiceData.getInstance (). getMyData (). osserva ...
Darish

3
Mi mancherà LocalBroadcastManager. Se è stato fonte di confusione per gli sviluppatori di Google, forse devono smettere di progettare troppo?
AFD

@Darish Questa classe singleton equivarrebbe a memorizzarla nell'oggetto Application? Perché questo tipo di stato globale in questi casi non è considerato una cattiva pratica?
xuiqzy,

6

Quando giocherai abbastanza con LocalBroadcastReceiver ti suggerirò di provare EventBus di Green Robot: ti renderai sicuramente conto della differenza e dell'utilità rispetto a LBR. Meno codice, personalizzabile sul thread del destinatario (UI / Bg), controllo della disponibilità dei ricevitori, eventi permanenti, eventi potrebbero essere utilizzati come consegna dei dati ecc.



0
enter code here if (createSuccses){
                        val userDataChange=Intent(BRODCAST_USER_DATA_CHANGE)
                        LocalBroadcastManager.getInstance(this).sendBroadcast(
                            userDataChange
                        )
                        enableSpinner(false)
                        finish()

0

Dichiarandone uno nel file AndroidManifest.xml con il tag (chiamato anche statico)

<receiver android:name=".YourBrodcastReceiverClass"  android:exported="true">
<intent-filter>
    <!-- The actions you wish to listen to, below is an example -->
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>

Noterai che il ricevitore di trasmissione dichiarato sopra ha una proprietà di exported "true". Questo attributo indica al destinatario che può ricevere trasmissioni al di fuori dell'ambito dell'applicazione.
2. O dinamicamente registrando un'istanza con registerReceiver (ciò che è noto come contesto registrato)

public abstract Intent registerReceiver (BroadcastReceiver receiver, 
            IntentFilter filter);

public void onReceive(Context context, Intent intent) {
//Implement your logic here
}

Esistono tre modi per inviare le trasmissioni:
il metodo sendOrderedBroadcast consente di inviare le trasmissioni a un solo ricevitore alla volta. Ciascuna trasmissione può a sua volta passare i dati a quello successivo o interrompere la propagazione della trasmissione ai ricevitori che seguono.
SendBroadcast è simile al metodo sopra menzionato, con una differenza. Tutti i ricevitori di trasmissione ricevono il messaggio e non dipendono l'uno dall'altro.
Il metodo LocalBroadcastManager.sendBroadcast invia solo trasmissioni ai destinatari definiti all'interno dell'applicazione e non supera l'ambito dell'applicazione.


-4

possiamo anche usare l'interfaccia per lo stesso di broadcastManger qui sto condividendo il codice testd per broadcastManager ma tramite l'interfaccia.

prima fai un'interfaccia come:

public interface MyInterface {
     void GetName(String name);
}

2-questa è la prima classe che necessita di implementazione

public class First implements MyInterface{

    MyInterface interfc;    
    public static void main(String[] args) {
      First f=new First();      
      Second s=new Second();
      f.initIterface(s);
      f.GetName("Paddy");
  }
  private void initIterface(MyInterface interfc){
    this.interfc=interfc;
  }
  public void GetName(String name) {
    System.out.println("first "+name);
    interfc.GetName(name);  
  }
}

3-ecco la seconda classe che implementa la stessa interfaccia il cui metodo chiama automaticamente

public class Second implements MyInterface{
   public void GetName(String name) {
     System.out.println("Second"+name);
   }
}

quindi con questo approccio possiamo usare l'interfaccia funzionante come broadcastManager.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.