简体   繁体   English

跨多个进程的Otto / EventBus

[英]Otto/EventBus across multiple processes

Is it possible to post event in one process (for example inside SyncAdapter which has android:process=":sync" manifest attribute) and receive it in another (inside regular app UI) with Otto or EventBus ? 是否可以在一个进程中post事件(例如在具有android:process=":sync"清单属性的SyncAdapter内部)并使用OttoEventBus在另一个android:process=":sync"中(在常规应用UI内部)接收它?

I know that Intent and BroadcastReceiver work just fine for communication across multiple processes but I would like to have simplicity and flexibility with Otto/EventBus. 我知道IntentBroadcastReceiver可以很好地协调多个进程的通信,但我希望Otto / EventBus具有简单性和灵活性。

No, that is not possible, as Otto, greenrobot's EventBus, and LocalBroadcastManager are all in-process solutions. 不,这是不可能的,因为Otto,greenrobot的EventBus和LocalBroadcastManager都是进程内解决方案。

You might consider simply removing the android:process attribute from the manifest, so it all runs in one process. 您可以考虑从清单中删除android:process属性,因此它们都在一个进程中运行。

I know this question is a bit old, but there seems to be a library that claims it can handle a cross-process communication with an event-bus/Rx style architecture. 我知道这个问题有点陈旧,但似乎有一个库声称它可以处理与事件总线/ Rx样式架构的跨进程通信。

https://github.com/edisonw/PennStation https://github.com/edisonw/PennStation

Disclaimer: I have not tried this, just found it and it claims to do what this question is asking. 免责声明:我没有尝试过这个,只是发现了它,它声称做了这个问题的问题。

I know the answer was already accepted but I thought I'd write about how I solved the problem in case anyone runs across this and is curious how the code might look like. 我知道答案已被接受,但我想我会写一些关于我是如何解决这个问题的,如果有人遇到这个问题并且很好奇代码的样子。

If you are using Otto, I followed the accepted answer above by removing the android:process from the manifest. 如果您正在使用Otto,我通过从清单中删除android:process来遵循上面接受的答案。 I also followed the answer provided here How to send event from Service to Activity with Otto event bus? 我也按照这里提供的答案如何使用Otto事件总线将事件从Service发送到Activity? , where a Bus exception was being thrown for not being run on the main thread. ,因为没有在主线程上运行而抛出了一个Bus异常。 Therefore I combined the two answers and created a bus to be executed on the main thread as per the link above. 因此,我结合了两个答案,并根据上面的链接创建了一个在主线程上执行的总线。

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

I then created a Bus singleton that can used anywhere in the application: 然后我创建了一个可以在应用程序中的任何位置使用的Bus单例:

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

    public static MainThreadBus getInstance() {
        return BUS;
    }

    private BusProvider() {
    }
}

In my SyncAdapter I used the following code initiate the event, BusProvider.getInstance().post(event); 在我的SyncAdapter中,我使用以下代码启动事件, BusProvider.getInstance().post(event); and in my application fragment I simply subscribed to the event. 在我的应用程序片段中,我只是订阅了该事件。

This worked perfectly fine when the application was in the foreground as well as when the sync adapter was initiated in the background after the application was swiped away. 当应用程序处于前台以及在应用程序被刷掉后在后台启动同步适配器时,这非常正常。

No, but you can use transit . 不, 但你可以使用过境 For example using BroadcastReceiver : In one process, send a broadcast with your data, then through the interior of BroadcastReceiver onReceive methods, post a otto event. 例如,使用BroadcastReceiver :在一个过程中,使用您的数据发送broadcast ,然后通过BroadcastReceiver onReceive方法的内部发布一个otto事件。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM