2014-08-29 3 views
10

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

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

ответ

12

Нет, это невозможно, так как Отто, EventBus от greenrobot и LocalBroadcastManager - это все входящие в процесс решения.

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

+0

Но тогда я бы потерял функциональность 'sync', если приложение закрыто (потому что процесс': sync' является общим общим и работает в фоновом режиме)? «Атрибут android: exported =« true »позволяет другим процессам, кроме вашего приложения (включая систему) обращаться к Сервису. Атрибут android: process =": ​​sync "сообщает системе о запуске службы в глобальном совместном процессе с именем sync «. - http://developer.android.com/training/sync-adapters/creating-sync-adapter.html#DeclareSyncAdapterManifest – svenkapudija

+1

@svenkapudija: Вам не нужно использовать 'android: process =": ​​sync "' использовать ' SyncAdapter'.«потому что: процесс синхронизации является общим общим и работает в фоновом режиме» - это было бы общим для нескольких ваших компонентов, которые используют «android: process =»: sync «'. [Это не было бы распространено ни с чем другим на устройстве] (http://developer.android.com/guide/topics/manifest/service-element.html#proc). – CommonsWare

+0

Также считалось, что для синхронизации SyncAdapter в фоновом режиме требуется синхронизация: sync. Оказывается, это не так, и, удалив его, вы можете синхронизировать в фоновом режиме, пока ваш пользовательский интерфейс (через Otto или Broadcasts) знает, что что-то произошло. – Entreco

0

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

Если вы используете Отто, я выполнил принятый ответ выше, удалив android:process из манифеста. Я также выполнил ответ, приведенный здесь How to send event from Service to Activity with Otto event 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); и в моем фрагменте приложения я просто подписался событие.

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

0

No, но вы можете использовать транзит. Например, используя BroadcastReceiver: В один процесс отправьте broadcast с вашими данными, затем во внутреннюю область BroadcastReceiveronReceive методов, разместите событие 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)); 
     } 
    } 
} 
1

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

https://github.com/edisonw/PennStation

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

Смежные вопросы