Question

Android doc says: "Each Handler instance is associated with a single thread.."

So, if I define the following handler inside onCreate() method:

myHandler= new Handler();

then myHandler will be associated with the main (UI) thread?

I would like to see an example where a handler is "associated" with a worker thread. If you have any, I would appreciate. Thanks.

Était-ce utile?

La solution

There are two questions here.

The answer to the first is "yes". If that line of code is in onCreate, then myHandler is associated with the UI thread

A Handler is cannot be associated with just any thread. It must be associated with a Looper. The very first paragraph of the documentation of the Looper gives an example.

Autres conseils

This much is true: If you use the default constructor for Handler, then your Handler object will be associated with the current thread - whatever it is.

However, you will note that the Handler class has several other constructors. If you provide the Looper argument to the Handler constructor, then your handler will be associated with the thread that is associated with the Looper. (Note that Looper detects and holds onto the thread that it is constructed in.)

You can create a Thread with a Looper by instantiating a Looper in the thread's run() method. But Android has already done this for you in the HandlerThread class: HandlerThread class is a subclass of Thread and has a Looper - perhaps a better name for HandlerThread would have been LooperThread. In any case, HandlerThread class also has a method called getLooper(). So, you first create an instance of HandlerThread, and then use its getLooper() as an argument to your Handler constructor:

    HandlerThread myLooperThread=new HandlerThread("LooperThread");   
    myLooperThread.start();                                           
    Handler myLooperHandler=new Handler (myLooperThread.getLooper(), 
                                         new MyLooperHandlerCallback());
    myLooperHandler.sendEmptyMessage(50);

The above snippet can be executed in your UI thread, but will still associate myLooperHandler with the HandlerThread's thread. You can verify this, by logging thread id, as in:

   //runs in HandlerThread's thread
   public class MyHandlerCallback implements Callback {

       @Override
       public boolean handleMessage(Message msg) {
           Log.i("CALLBACK", "Thread ID:"+android.os.Process.myTid());
           Log.i("CALLBACK", "msg.what:"+msg.what);
           return true;
       }
  }

Note that it is best to instantiate threads in retained worker fragments, so that they are accessible across Activity boundaries.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top