Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Otto to refresh a listadapter from a GcmListenerService

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

    }
}

}

like image 226
Brandon Avatar asked Oct 31 '22 23:10

Brandon


1 Answers

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!

like image 172
Brandon Avatar answered Nov 15 '22 06:11

Brandon