2014-08-29 15 views
10

Ist es möglich, post Ereignis in einem Prozess (zum Beispiel innerhalb SyncAdapter des android:process=":sync" manifest -Attribut) und empfängt sie in einem anderen (innerhalb regulären UI app) mit Otto oder EventBus?Otto/EventBus über mehrere Prozesse

Ich weiß, dass Intent und BroadcastReceiver funktionieren gut für die Kommunikation über mehrere Prozesse, aber ich möchte Einfachheit und Flexibilität mit Otto/EventBus haben.

Antwort

12

Nein, das ist nicht möglich, da Otto, greenrobots EventBus und LocalBroadcastManager alle In-Process-Lösungen sind.

Sie könnten einfach das android:process-Attribut aus dem Manifest entfernen, sodass alles in einem Prozess ausgeführt wird.

+0

Aber dann würde ich "Sync" -Funktion verlieren, wenn App geschlossen ist (weil ': Sync' Prozess ist häufig geteilt und arbeitet im Hintergrund)? "Das Attribut android: exported =" true "ermöglicht anderen Prozessen als Ihrer App (einschließlich des Systems) den Zugriff auf den Dienst. Das Attribut android: process =": ​​sync "weist das System an, den Dienst in einem globalen freigegebenen Prozess namens sync auszuführen . " - http://developer.android.com/training/sync-adapters/creating-sync-adapter.html#DeclareSyncAdapterManifest – svenkapudija

+1

@svenkapudija: Sie müssen 'android: process =": ​​sync "' nicht verwenden, um '' zu verwenden SyncAdapter'."weil: sync process ist häufig geteilt und arbeitet im hintergrund" - es wäre üblich, dass mehrere ihrer komponenten 'android: process =": ​​sync "' verwenden. [Es wäre mit nichts auf dem Gerät anders] (http://developer.android.com/guide/topics/manifest/service-element.html#proc). – CommonsWare

+0

Auch dachte, dass die: Sync für den SyncAdapter im Hintergrund ausgeführt werden benötigt. Stellt sich heraus, dass dies nicht der Fall ist, und indem Sie es entfernen, können Sie im Hintergrund synchronisieren, während Ihre Benutzeroberfläche (über Otto oder Broadcasts) weiß, dass etwas passiert – Entreco

0

Ich weiß, dass die Antwort bereits akzeptiert wurde, aber ich dachte, ich würde darüber schreiben, wie ich das Problem gelöst habe, falls jemand darüber stolpert und neugierig ist, wie der Code aussehen könnte.

Wenn Sie Otto verwenden, folgte ich der oben genannten Antwort, indem Sie die android:process aus dem Manifest entfernen. Ich folgte auch der Antwort, die hier How to send event from Service to Activity with Otto event bus? zur Verfügung gestellt wurde, wo eine Bus-Ausnahme geworfen wurde, um nicht auf dem Hauptthread ausgeführt zu werden. Daher habe ich die beiden Antworten kombiniert und einen Bus erstellt, der auf dem Hauptthread gemäß dem obigen Link ausgeführt werden soll.

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); 
       } 
      }); 
     } 
    } 
} 

Ich habe dann ein Bus Singleton, die überall in der Anwendung verwendet werden können:

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

    public static MainThreadBus getInstance() { 
     return BUS; 
    } 

    private BusProvider() { 
    } 
} 

In meinem SyncAdapter habe ich den folgenden Code an der Veranstaltung, BusProvider.getInstance().post(event); und in meiner Anwendung Fragment initiieren ich einfach abonniert das Ereignis.

Dies funktionierte einwandfrei, wenn die Anwendung im Vordergrund war und wenn der Synchronisierungsadapter im Hintergrund gestartet wurde, nachdem die Anwendung entfernt wurde.

0

Nein, aber Sie können Transit verwenden. Zum Beispiel mit BroadcastReceiver: In einem Prozess senden Sie eine broadcast mit Ihren Daten, dann durch das Innere von BroadcastReceiveronReceive Methoden, ein OTTO-Ereignis.

Wie meine Codes:

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

Ich weiß, diese Frage ist ein bisschen alt, aber es scheint, eine Bibliothek zu sein, dass sie behauptet kann eine prozessübergreifende Kommunikation mit einer Ereignis-Bus/Rx-Architektur behandeln .

https://github.com/edisonw/PennStation

Disclaimer: Ich nicht versucht haben, fanden es einfach und es behauptet, zu tun, was diese Frage zu stellen ist.