Как отправить событие из службы в действие с помощью шины событий Otto?
простой BusProvider.getInstance().post()
принести исключение не main thread
.
Как отправить событие из службы в действие с помощью шины событий Otto?
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
через aBus
ссылка.
или просто сделайте это, если вы уверены, что вы публикуете из неосновного потока:
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)); } } }