Android Looper oddness

Good Android development, heck good development, requires none ui blocking interactions.

As part of that (I can’t take credit, I think Dorian Cussen came up with the original idea) I have a nice Java method in my Base Ui classes to handle making sure UI actions happen on the UI thread away from a background thread they may of been called from.

The methods are as follows:

/**
 * Add a runnable task that can only be run during the activity being alive, things like dismissing dialogs when a background
 * task completes when the user is away from the activity.
 *
 * @param runnable runnable to run during the ui being alive.
 */
protected void postUiRunnable(final Runnable runnable)
{
    QLog.v("UiRunnables = " + runnable);
    if (null == runnable){
        return;
    }
    if (!mIsPaused && BaseActivity.isUiThread())
    {
        runnable.run();
    }
    else if (!mIsPaused && !BaseActivity.isUiThread() && getActivity() != null)
    {
        getActivity().runOnUiThread(runnable);
    }
    else
    {
        mUiRunnables.add(runnable);
    }
}

The idea being you push your UI calls onto this method which makes sure you don’t manipulate the UI outside of runtime and what is visible to the user. Simple right!
Well it would be up to this point here: BaseActivity.isUiThread()

This calls a convenance method to check which thread you are calling from.

public static boolean isUiThread()
{
    return Looper.getMainLooper().equals(Looper.myLooper());
}

Great right? Yes. But make sure that your Looper check is done in the above order.

THIS WILL NOT WORK return Looper.myLooper().equals(Looper.getMainLooper());

If the myLooper is cleared/consumed for what ever reason the execution just stops here. No not fails or errors, STOPS! I would need to look into the Android framework to give you a solid answer why.

Suffice to say, Always use the Looper.getMainLooper(), if your application IS running then this this is always a valid object.