2014-05-11 12 views
7

Ora attività in grado di connettersi ai servizi utilizzando uno dei tre modi:Qual è il modo migliore per comunicare tra servizio e attività?

Penso che BroadcastReceivers è il modo più semplice per comunicare, ma mi chiedo perché e quando usare altri modi? o in altre parole in quali casi i messenger o AIDL saranno la migliore pratica da usare rispetto ai broadcastreceivers?

+1

Dovresti iniziare a considerare se il tuo servizio è in esecuzione nello stesso processo della tua attività o se è in esecuzione su un processo diverso dalla tua attività. – Eido95

+0

yeah Ho usato il binding prima e nel mio ultimo progetto, ho usato broadcast e broadcast sono molto più facili da usare con – yeahman

risposta

8

È possibile utilizzare BroadcastReceiver quando w nella comunicazione tra Service e Activity nell'applicazione.

Messenger 's e AIDL vengono utilizzati principalmente quando l'applicazione deve comunicare con altri processi (IPC). In questo caso la tua interfaccia dovrebbe avere un Service che definisce un Handler che risponde a diversi tipi di oggetti Message.

Ora la differenza tra Messenger e AIDL è piuttosto semplice. Quando si utilizza Messenger, esso accoda tutte le richieste in un singolo thread. Quindi il tuo Service non deve essere thread-safe. Se vuoi che il tuo Service gestisca più richieste contemporaneamente, puoi utilizzare direttamente AIDL. In questo caso, il tuo Service deve essere capace di multi-threading ed essere costruito thread-safe. Infatti, Messenger è implementato nella parte superiore di AIDL.

Per una migliore comprensione un'occhiata a Bound Services

Si dovrebbe anche controllare la risposta da BroadcastReceiver or Messenger via Handler

10

Principalmente uso lo LocalBroadcasts. Essenzialmente sono come trasmissioni reali, ma sono visibili solo alla tua applicazione. In primo luogo è necessario creare un BroadcastReceiver come si farebbe con una trasmissione normale:

private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 
     if(Intent.SOME_ACTION.equals(action)) { 
      // Do your work 
     } 
    } 
}; 

È possibile quindi registrare e annullare la registrazione del BroadcastReceiver in questo modo:

@Override 
public void onResume() { 
    super.onResume(); 

    IntentFilter intentFilter = new IntentFilter(Intent.SOME_ACTION); 

    LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity()); 
    manager.registerReceiver(broadcastReceiver, intentFilter); 
} 

@Override 
public void onPause() { 
    super.onPause(); 

    LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity()); 
    manager.unregisterReceiver(broadcastReceiver); 
} 

E, infine è possibile inviare una trasmissione dal Service o in qualsiasi altro nella vostra applicazione in questo modo:

Intent intent = new Intent(Intent.SOME_ACTION); 

LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity()); 
manager.sendBroadcast(intent); 
+2

concordato. Questo, o bus di messaggi di terze parti (Square's Otto, eventrobus di greenrobot), sono le migliori pratiche attuali. – CommonsWare

+0

Thx molto, ma mi chiedo quando usare i messaggeri !! –

+0

'Messengers' non sono comunemente usati, questo è anche il motivo per cui c'è così poca documentazione sull'argomento. Sono principalmente utilizzati per comunicare tra diversi processi. –

2

Se il service is used only by the local application e non ha bisogno di lavorare in tutti i processi, quindi è possibile implementare il proprio Binder class che fornisce al vostro cliente diretto accesso a public methods in the service.

Nota: questo funziona solo se il client e il servizio si trovano nella stessa applicazione e processo`, che è il più comune.

estensione della classe Binderhttp://developer.android.com/guide/components/bound-services.html#Binder

3

Xaver risposta Kapeller s' è davvero una buona. Tuttavia, ha un (maggiore) svantaggio: le trasmissioni possono essere perse.

Quando l'utente si sposta lontano dal Activity (ad esempio mostrando le applicazioni recenti), è la registrazione del proprio BroadcastReceiver s. Se la trasmissione viene inviata in quel momento, il tuo Activity non lo riceve. Quando si ritorna al tuo Activity, potrebbe essere in uno stato non valido.


Utilizzando un ResultReceiver, in questo caso si riceve comunque il risultato. Inoltre, uno ResultReceiver è parcelable, quindi è possibile salvarlo e ripristinarlo negli eventi del ciclo di vita.
Tuttavia, causa qualche sovraccarico, motivo per cui ho creato this experimental library per semplificare un po '. Per ora utilizza solo IntentService s, ma dovrebbe essere abbastanza semplice da estendere.

+0

Sì, è vero che le trasmissioni possono essere perse, ma normalmente se la tua app dipende assolutamente dalla ricezione della trasmissione di quanto tu stia facendo qualcosa di sbagliato. Le trasmissioni locali non dovrebbero mai essere utilizzate per trasferire dati o cose del genere. Un caso d'uso per le trasmissioni locali, ad esempio, è che notificate un frammento che un'operazione è stata completata oi dati sono cambiati e devono essere ricaricati, in altre parole cose che sono irrilevanti per lo stato dell'app stessa, semplicemente danno extra - ma essenzialmente inutile - informazioni. –

Problemi correlati