跨多个进程的Otto / EventBus

时间:2014-08-29 12:20:49

标签: android android-syncadapter otto greenrobot-eventbus

是否可以在一个进程中post事件(例如,SyncAdapter内部有android:process=":sync"清单属性)并在另一个进程中(在常规应用UI内部)使用{{3 }或Otto

我知道IntentBroadcastReceiver可以很好地协调多个流程,但我希望Otto / EventBus具有简单性和灵活性。

4 个答案:

答案 0 :(得分:14)

不,这是不可能的,因为Otto,greenrobot的EventBus和LocalBroadcastManager都是进程中的解决方案。

您可以考虑从清单中删除android:process属性,这样就可以在一个进程中运行。

答案 1 :(得分:1)

我知道这个问题有点陈旧,但似乎有一个图书馆声称它可以处理与事件总线/ Rx风格架构的跨进程通信。

https://github.com/edisonw/PennStation

免责声明:我没有尝试过这个,只是发现了它并声称要做这个问题的问题。

答案 2 :(得分:0)

我知道答案已被接受,但我想我会写一篇关于我是如何解决这个问题的,如果有人遇到这个问题,并且很好奇代码的样子。

如果您使用的是Otto,我会通过从清单中删除android:process来遵循上面接受的答案。我也按照这里提供的答案How to send event from Service to Activity with Otto event bus?,其中因为没有在主线程上运行而抛出了一个Bus异常。因此,我结合了两个答案,并根据上面的链接在主线程上创建了一个总线。

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

然后我创建了一个可以在应用程序中的任何位置使用的总线单例:

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

    public static MainThreadBus getInstance() {
        return BUS;
    }

    private BusProvider() {
    }
}

在我的SyncAdapter中,我使用以下代码启动事件BusProvider.getInstance().post(event);,在我的应用程序片段中,我只是订阅了该事件。

当应用程序处于前台以及在应用程序被刷掉后在后台启动同步适配器时,这非常正常。

答案 3 :(得分:0)

不,但您可以使用中转。例如,使用BroadcastReceiver:在一个过程中,使用您的数据发送broadcast,然后通过BroadcastReceiver onReceive方法的内部发布otto事件。

和我的代码一样:

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