Отто/EventBus для нескольких процессов

Возможно ли событие post в одном процессе (например, внутри SyncAdapter, которое имеет атрибут android:process=":sync" manifest)) и получать его в другом (внутри обычного пользовательского интерфейса приложения) с Otto или EventBus?

Я знаю, что Intent и BroadcastReceiver работают очень хорошо для общения по нескольким процессам, но я бы хотел иметь простоту и гибкость с Otto/EventBus.

Ответ 1

Нет, это невозможно, так как Otto, greenrobot EventBus и LocalBroadcastManager - все это неотложные решения.

Вы можете просто удалить атрибут android:process из манифеста, чтобы он выполнялся в одном процессе.

Ответ 2

Я знаю, что этот вопрос немного устарел, но, похоже, есть библиотека, которая утверждает, что может обрабатывать межпроцессное взаимодействие с архитектурой стиля event-bus/Rx.

https://github.com/edisonw/PennStation

Отказ от ответственности: я не пробовал это, просто нашел его, и он утверждает, что делает то, что задает этот вопрос.

Ответ 3

Я знаю, что ответ уже принят, но я подумал, что напишу о том, как я решил проблему на случай, если кто-то столкнется с этим, и мне любопытно, как выглядит код.

Если вы используете Отто, я выполнил принятый ответ выше, удалив android:process из манифеста. Я также следил за предоставленным здесь ответом Как отправить событие из службы на активность с шиной событий Otto?, где исключалось исключение шины, которое не запускалось в основном потоке, Поэтому я объединил два ответа и создал шину для выполнения на основном потоке в соответствии с приведенной выше ссылкой.

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);, и в своем фрагменте приложения я просто подписался на это событие.

Это работало отлично, когда приложение находилось на переднем плане, а также когда инициатор синхронизации был инициирован в фоновом режиме после того, как приложение было удалено.

Ответ 4

Нет, , но вы можете использовать транзит. Например, используя 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));
        }
    }
}