问题
Simple BusProvider.getInstance().post()
bring exception not main thread
.
How to send event from Service to Activity with Otto event bus?
回答1:
To post from any thread (main or background) and receive on the main thread, try something like
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);
}
});
}
}
}
Note: credit goes to Jake Wharton and "pommedeterresaute" at https://github.com/square/otto/issues/38 for the general approach. I just implemented it with a wrapper class rather than a subclass.
回答2:
To post from any thread (main or background) and receive on the main thread, use the following MainThreadBus
instead of a vanilla 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);
}
});
}
}
}
This is based on Andy Dennie's answer.
There is no need to both extend and wrap a Bus
object, do one or the other. In Dennie's answer, which is effectively a wrapper, the Bus
base class is just being used like an interface, all the functionality is overwritten.
It would work even if you removed the Bus
base class unless you happened to reference the MainThreadBus
via a Bus
reference.
回答3:
Or simply do this if you're sure that you're posting from a Non-main thread:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
mBus.post(new myEvent());
}
});
Just as the saying goes, "Keep It Simple and Stupid" :)
回答4:
bus = new Bus(ThreadEnforcer.ANY); is the clear solution to this problem. Its all you have to do.
回答5:
Best implementation custom bus class for me
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));
}
}
}
回答6:
I did it simply:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
bus.post(event);
}
});
Happy coding.. :)
回答7:
Just create the BasicBus
with ThreadEnforcer.NONE
to post event from non-main threads. The mentioned ThreadEnforcer.MAIN
is exactly the opposite (and the default), which accepts only posts from the main-thread.
来源:https://stackoverflow.com/questions/15431768/how-to-send-event-from-service-to-activity-with-otto-event-bus