Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Possible for background thread to block until UI thread finishes operation?

Is it possible for a background thread to enqueue a message to the main UI thread's handler and block until that message has been serviced?

The context for this is that I would like my remote service to service each published operation off its main UI thread, instead of the threadpool thread from which it received the IPC request.

like image 717
zer0stimulus Avatar asked Jul 19 '10 22:07

zer0stimulus


People also ask

Is it ever okay block the UI thread?

1 Answer. Show activity on this post. You should never block UI Thread. When you hold UI Thread for too long, this is when the system will show a dialog saying XXX is not responding and ask user to kill your application.

Which method is used to go back to UI thread from a background thread?

onReceive(Context, Intent) method is called within the main thread by default. So you can use it to update the UI on the main thread.

Can we update UI from background thread?

In this case, to update the UI from a background thread, you can create a handler attached to the UI thread, and then post an action as a Runnable : Handler handler = new Handler(Looper. getMainLooper()); handler. post(new Runnable() { @Override public void run() { // update the ui from here } });

Why should you avoid to run non UI code on the main thread?

All Android apps use a main thread to handle UI operations. Calling long-running operations from this main thread can lead to freezes and unresponsiveness. For example, if your app makes a network request from the main thread, your app's UI is frozen until it receives the network response.


1 Answers

This should do what you need. It uses notify() and wait() with a known object to make this method synchronous in nature. Anything inside of run() will run on the UI thread and will return control to doSomething() once finished. This will of course put the calling thread to sleep.

public void doSomething(MyObject thing) {
    String sync = "";
    class DoInBackground implements Runnable {
        MyObject thing;
        String sync;

        public DoInBackground(MyObject thing, String sync) {
            this.thing = thing;
            this.sync = sync;
        }

        @Override
        public void run() {
            synchronized (sync) {
                methodToDoSomething(thing); //does in background
                sync.notify();  // alerts previous thread to wake
            }
        }
    }

    DoInBackground down = new DoInBackground(thing, sync);
    synchronized (sync) {
        try {
            Activity activity = getFromSomewhere();
            activity.runOnUiThread(down);
            sync.wait();  //Blocks until task is completed
        } catch (InterruptedException e) {
            Log.e("PlaylistControl", "Error in up vote", e);
        }
    }
}
like image 197
Ryan Avatar answered Sep 21 '22 04:09

Ryan