Как отправить событие из службы в действие с помощью шины событий Otto?


простой BusProvider.getInstance().post() принести исключение не main thread. Как отправить событие из службы в действие с помощью шины событий Otto?

7 57

7 ответов:

чтобы опубликовать из любого потока (основного или фонового) и получить в основном потоке, попробуйте что-то вроде

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

Примечание: кредит идет к Джейку Уортону и "pommedeterresaute" в https://github.com/square/otto/issues/38 для общего подхода. Я просто реализовал его с помощью класса-оболочки, а не подкласса.

чтобы опубликовать из любого потока (основного или фонового) и получить в основном потоке, используйте следующее MainThreadBus вместо ванили Bus

public class MainThreadBus extends Bus {
     private final Handler handler = new Handler(Looper.getMainLooper());

     @Override public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    MainThreadBus.super.post(event);
                }
            });
        }
    }
}

это основано на ответе Энди Денни.

нет необходимости как расширять, так и обертывать Bus объект, сделайте то или другое. В ответе Денни, который фактически является оберткой,Bus базовый класс просто используется как интерфейс, все функции перезаписываются.

Она будет работать даже если вы удалили Bus базовый класс, если вы случайно не ссылаетесь на MainThreadBus через a Bus ссылка.

или просто сделайте это, если вы уверены, что вы публикуете из неосновного потока:

new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        mBus.post(new myEvent());
                    }
                });

Как говорится, "держите его простым и глупым" :)

bus = новая шина (ThreadEnforcer.Любой); является ясным решением этой проблемы. Все, что вам нужно сделать.

лучшая реализация пользовательского класса шины для меня

public class AndroidBus extends Bus {
    private final Handler mainThread = new Handler(Looper.getMainLooper());

    @Override
    public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            mainThread.post(() -> AndroidBus.super.post(event));
        }
    }
}

Я сделал это просто:

Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                bus.post(event);
            }

        });

удачи в кодировании.. :)

просто создать BasicBus с ThreadEnforcer.NONE для публикации события из неосновных потоков. Упомянутое ThreadEnforcer.MAIN точно наоборот (и по умолчанию), который принимает только сообщения из основного потока.