2014-08-29 14 views
10

E 'possibile post evento in un unico processo (ad esempio all'interno di SyncAdapter che ha android:process=":sync" attributo manifesto) e ricevere in un altro (all'interno regolare app UI) con Otto o EventBus?Otto/EventBus tra più processi

So che Intent e funzionano perfettamente per la comunicazione tra più processi, ma mi piacerebbe avere semplicità e flessibilità con Otto/EventBus.

risposta

12

No, non è possibile, poiché Otto, EventBus di greenrobot e LocalBroadcastManager sono tutte soluzioni in-process.

È possibile semplicemente rimuovere l'attributo android:process dal manifest, in modo che venga eseguito tutto in un unico processo.

+0

Ma poi perderei la funzionalità 'sync' se l'app è chiusa (perché il processo': sync' è condiviso e funziona in background)? "L'attributo android: exported =" true "consente ai processi diversi dall'app (incluso il sistema) di accedere al Servizio. L'attributo android: process =": ​​sync "indica al sistema di eseguire il Servizio in un processo condiviso globale denominato sync ". - http://developer.android.com/training/sync-adapters/creating-sync-adapter.html#DeclareSyncAdapterManifest – svenkapudija

+1

@svenkapudija: Non è necessario utilizzare 'android: process =": ​​sync "' per usare a ' SyncAdapter'."perché: il processo di sincronizzazione è condiviso in comune e funziona in background" - sarebbe comune tra molti dei tuoi componenti che usano 'android: process =": ​​sync "'. [Non sarebbe in comune con nient'altro sul dispositivo] (http://developer.android.com/guide/topics/manifest/service-element.html#proc). – CommonsWare

+0

Inoltre, si pensava che il: sync fosse necessario per SyncAdapter per l'esecuzione in background. Risulta che non è il caso, e rimuovendolo puoi sincronizzarlo in background mentre permetti alla tua interfaccia utente di sapere (tramite Otto o Trasmissioni) che qualcosa è successo – Entreco

0

So che la risposta è stata già accettata, ma ho pensato di scrivere su come ho risolto il problema nel caso in cui qualcuno si imbattesse in questo ed è curioso di sapere come potrebbe apparire il codice.

Se si utilizza Otto, ho seguito la risposta accettata in precedenza rimuovendo il file android:process dal manifest. Ho seguito anche la risposta fornita qui How to send event from Service to Activity with Otto event bus?, dove veniva lanciata un'eccezione Bus per non essere eseguita sul thread principale. Pertanto ho combinato le due risposte e creato un bus da eseguire sul thread principale come da link sopra.

public class MainThreadBus extends Bus { 
    private final Handler mHandler = new Handler(Looper.getMainLooper()); 
    @Override 
    public void post(final Object event) { 
     if (Looper.myLooper() == Looper.getMainLooper()) { 
      super.post(event); 
     } else { 
      mHandler.post(new Runnable() { 
       @Override 
       public void run() { 
        MainThreadBus.super.post(event); 
       } 
      }); 
     } 
    } 
} 

Ho quindi creato un Singleton Bus che può usato qualsiasi punto dell'applicazione:

public final class BusProvider { 
    private static final MainThreadBus BUS = new MainThreadBus(); 

    public static MainThreadBus getInstance() { 
     return BUS; 
    } 

    private BusProvider() { 
    } 
} 

Nel mio SyncAdapter ho usato il seguente codice avviare l'evento, BusProvider.getInstance().post(event); e nel mio frammento applicazione che ho semplicemente sottoscritto l'evento.

Questo ha funzionato perfettamente quando l'applicazione era in primo piano e quando l'adattatore di sincronizzazione è stato avviato in background dopo che l'applicazione è stata trascinata via.

0

No, ma è possibile utilizzare il transito. Ad esempio, utilizzando BroadcastReceiver: in un processo, invia un broadcast con i tuoi dati, quindi attraverso i metodi interni di BroadcastReceiveronReceive, pubblica un evento di otto.

Come i miei codici:

public class ReceiveMessageBroadcastReceiver extends BroadcastReceiver { 

    public static final String ACTION_RECEIVE_MESSAGE 
      = "me.drakeet.xxxxxx.ACTION_RECEIVE_MESSAGE"; 
    public static final String AGR_MESSAGE = "AGR_MESSAGE"; 


    // this method can be called in other processes 
    public static void sendBroadcast(Context context, MessageContent content) { 
     Intent intent = new Intent(); 
     intent.setAction(ACTION_RECEIVE_MESSAGE); 
     intent.putExtra(AGR_MESSAGE, content); 
     context.sendBroadcast(intent); 
    } 


    // this method will run in your default process, so you can post otto events to your 
    // default process 
    @Override public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 
     if (action.equals(ACTION_RECEIVE_MESSAGE)) { 
      MessageContent content = intent.getParcelableExtra(AGR_MESSAGE); 
      Otto.getSeat().post(new PlayMessageReceivedEvent(content)); 
     } 
    } 
} 
1

So che questa domanda è un po 'vecchio, ma sembra che ci sia una libreria che afferma che in grado di gestire una comunicazione tra processi con una/Rx architettura in stile event-bus .

https://github.com/edisonw/PennStation

Disclaimer: Non ho provato questo, appena trovato e che dice di fare quello che a questa domanda sta chiedendo.

Problemi correlati