Daniël van den Berg
Daniël van den Berg

Reputation: 2355

Android runOnUiThread not async

I've got this piece of code:

public void updateOptionLists() {
    Log.d("UI", "Called update");
    if (updating){
        return;
    }
    updating = true;
    runOnUiThread(
            new Runnable() {
                @Override
                public void run() {
                    updating = false;
                    updateOptionList();
                    scrollToLastTapped();
                    Log.d("UI","Updating");
                }
            });
    Log.d("UI", "Posted update");
}

What I'd expect from logcat would be something like this:

As far as I know runOnUi should be asynchronous, right? And considering that the functions called alter the views, which takes a while, this should be running asynchronous. Right?

So I look at my logcat:

Why does this happen? And how do I make sure this runs asynchronous?

Upvotes: 2

Views: 2094

Answers (7)

Shawnse
Shawnse

Reputation: 51

Multi Threaded Programming: Theory vs Actual Puppy Photos Explain is the Best pic.twitter.com/adFy17MTTI

— Cian Ó Maidín (@Cianomaidin) 6. april 2015

But joke aside.

If you want to test how the threads work in correlation, try:

runOnUiThread(
        new Runnable() {
            @Override
            public void run() {
                updating = false;
                updateOptionList();
                scrollToLastTapped();
                Thread.sleep(100);
                Log.d("UI","Updating");
            }
        });

Upvotes: 0

stkent
stkent

Reputation: 20128

runOnUiThread will execute your code on the main thread, which (in this example) also appears to be where it's called from. This explains the ordering of the log statements you see - all code is executing on a single thread, so is synchronous per the documentation (my emphasis):

Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.

runOnUiThread is typically used to execute code on the main thread from a different (i.e. background thread). The use of this separate background thread is what will make a task asynchronous. Calling back to the UI thread at the end of that task is required if you want to modify UI with the results of your background thread calculations.

Android provides several mechanisms for doing work on a background thread and then posting back to the main thread (not all use runOnUiThread explicitly for the latter operation). Good things to read up on include Thread, Handler, AsyncTask, Service, etc.

Upvotes: 8

Kistamushken
Kistamushken

Reputation: 221

From the documentation:

Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

Upvotes: 0

Kevin Robatel
Kevin Robatel

Reputation: 8386

For accessing the view, you must be in the UI Thread (the main one). So, runOnUiThread will be executed on it.

You must do the long work in an other thread and only call runOnUiThread for little thing like changing a color or a text but not to calculating it.

Upvotes: 0

Sattar Hummatli
Sattar Hummatli

Reputation: 1408

Because you call upadetOptionLists() on ui prosess, upadetOptionLists() and runUiThread() both run in the same thread.

To separte theam you need run content in other new thread as following

   public void updateOptionLists() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                Log.d("UI", "Called update");
                if (updating){
                    return;
                }
                updating = true;
                runOnUiThread(
                        new Runnable() {
                            @Override
                            public void run() {
                                updating = false;
                                updateOptionList();
                                scrollToLastTapped();
                                Log.d("UI","Updating");
                            }
                        });
                Log.d("UI", "Posted update");
            }
        }).start();
    }

Upvotes: 0

Stephan Huewe
Stephan Huewe

Reputation: 124

is updateOptionLists running on the UI Thread?

If this is the case, i would expect this behavior to be ok.

In a normal case you use runOnUiThread from a background thread to come again to the Ui Thread..

Upvotes: 0

maciekjanusz
maciekjanusz

Reputation: 4775

As far as I know runOnUi should be asynchronous, right?

runOnUiThread, as the name states, runs on UI thread, which is a main thread of an application. It runs synchronously with other code running within that thread and asynchronously with code in other threads. The word 'asynchronous' has no meaning without a context: some code can run asynchronously with other parts of the code, which means these parts of the code run in different threads. Saying that something 'should be asynchronous' makes no sense without this kind of context.

Upvotes: 2

Related Questions