0

I have a simple question: is it possible to restart (re- loop()) thread's Looper if it was previously quit. For instance, i have design my thread as follow:

public class ProvaThread extends Thread implements Runnable{

        public void run(){

            Looper.prepare();
            Handler handler = new Handler(){
                Log.d(TAG, "handle message..");
                @Override
                public void handleMessage(Message msg){

                    getLooper().quit();
                }
            };

            Looper.loop(); //loop 1

            Log.d(TAG, "thread continue (1)...");

            Looper.loop(); //loop 2

            Log.d(TAG, "thread continue (2)...");

        }
    }

I have tried this code but i get a RuntimeException (sending message to a Handler on a dead thread) when i try to post a message to the handler the second time (handleMessage() is not called after second loop()). I came to conclusion that when getLooper().quit() is called is it possible to recall loop() but is it not possible to handle new messages, otherwise exception is thrown). Is it correct?

Should i use wait()/notify() to make this??

user1709805
  • 2,028
  • 3
  • 19
  • 26
  • Why are you calling looper.quit if you don't want it to run anymore? What you're trying to actually do isn't clear. – Gabe Sechan Jan 24 '13 at 22:05
  • Did you try to read aloud this code or explain it to someone else? It looks like this: 1. I'm creating messages queue 2. Now I'm adding messages handler which stops messages queue 3. Start messages queue 4. Show log 5. Start messages queue 6. Show log It's wrong. – Kamil Jan 24 '13 at 22:11
  • And hey, Log.d(TAG, "handle message.."); outside any method? – Kamil Jan 24 '13 at 22:16
  • The messages posted in the handler came from UI Thread (message contains a dialog resonse). You can read "thread continue (i)" as "continue elaboration (i)" and "Looper.loop()" as "post dialog in Ui thread, using another handler, and wait for response". Probably this isn't the right way to make this. – user1709805 Jan 24 '13 at 22:18
  • i want to perform a sort of ping-pong between UI Thread (dialog) and Worker Thread. Each elaboration step depends on dialog's response.. – user1709805 Jan 24 '13 at 22:21
  • yeah, you're right.. Log.d(TAG, "handle message..") is within handleMessage(). I made a mistake when i wrote the post.. – user1709805 Jan 24 '13 at 22:23

2 Answers2

3

Let me first explain why your example code doesn't work. A Looper only handles one, and only one, MessageQueue. This MessageQueue is created when you call Looper.prepare() and the messages are processed when you call Looper.loop(). Once you have called Looper.quit() two things happen:

  1. The MessageQueue to the Looper is put in a final terminal state where it will not process any incoming messages; a RuntimeException is thrown.
  2. It will only return "null" as message when the Looper tries to retrieve messages.

So, (1) is the reason for your RuntimeException and (2) allows you to try and and restart the message retrieval with Looper.loop() but only "null"-objects are returned from the MessageQueue.

Secondly, let me suggest a better approach to solve a continuous communication between the UI and a worker thread:

  1. Create a Handler for the UI thread, called mUiHandler.
  2. Create a worker thread, e.g. HandlerThread, and expose a Handler, called mWorkerHandler.

Now, let the two handlers communicate by sending messages back and forth. Post messages to the mWorkerHandler for background tasks and let the worker thread post messages to the mUiHandler whenever a dialog shall be shown or removed.

0

I think you should read this short article http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/. It explains how Looper works and how to use it.

Kamil
  • 2,712
  • 32
  • 39
  • My problem is performing a modal dialog that blocks the code flow untill the user responds!! I don't want to create a chain of Asynctask where in onPostExecute() i show the dialog and in doInBackground() make the heavy operations. I want to make this in only one task.. any suggestion? – user1709805 Jan 24 '13 at 22:41
  • Could you try explain the case which you're trying to implement? – Kamil Jan 24 '13 at 22:44