I'm using Otto to refresh a buddies list when a buddy debuddies me. I'm having issues updating the UI from a non-main thread, so I looked into it and 'solved' the issue using this post. The code they use is this:
public class BusProvider extends Bus{
public static final String LOG_TAG = BusProvider.class.getSimpleName();
private final Handler mainThread = new Handler(Looper.getMainLooper());
private static Bus mInstance;
public static synchronized Bus getInstance() {
if (mInstance == null) {
mInstance = new Bus();
}
return mInstance;
}
@Override
public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.d(LOG_TAG, "Posting event using super!");
super.post(event);
} else {
mainThread.post(new Runnable() {
@Override
public void run() {
Log.d(LOG_TAG, "Posting event using AndroidBus!");
BusProvider.super.post(event);
}
});
}
}
}
I make the post like this:
final Bus bus = BusProvider.getInstance();
Log.d(LOG_TAG, "Attempting to post from LBGcmListenerService!");
bus.post(new BuddiesEvent());
Essentially making a singleton Bus and posting through that, ensuring that it is on the main thread. However, I cannot get that code to work. I instead instantiated the Handler in the class I post from, as such:
final Bus bus = BusProvider.getInstance();
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
bus.post(new BuddiesEvent());
}
);
This works great. But I don't want to have to make a Handler object before every post. I don't know if this is a Java issue or an Android issue, but I would appreciate if somebody could help me figure out how to make the singleton class handle this issue. Thanks!
Fixed: Putting the correct code here:
public class BusProvider extends Bus{
public static final String LOG_TAG = BusProvider.class.getSimpleName();
private final Handler mainThread = new Handler(Looper.getMainLooper());
private static BusProvider mInstance;
public static synchronized BusProvider getInstance() {
if (mInstance == null) {
mInstance = new BusProvider();
}
return mInstance;
}
@Override
public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.d(LOG_TAG, "Posting event using super!");
super.post(event);
} else {
mainThread.post(new Runnable() {
@Override
public void run() {
Log.d(LOG_TAG, "Posting event using AndroidBus!");
BusProvider.super.post(event);
}
});
}
}
}
Yes, I figured it out. The answer here was nothing mysterious. In my singleton class, I was creating a Bus object and handing that over as the instance. I wasn't making a BusProvider. Therefore, when I called post, it wasn't calling the BusProvider overridden method but the Bus method, which wasn't "thread safe" in my case. After I changed the code to reflect this recognition, it worked great!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With