Advanced Android handler mechanism

Source: Internet
Author: User

An asynchronous callback mechanism is provided in Android handler, which allows us to make a notification after a long task has been completed

Handler Basic use:

In the main thread, using handler is simple, new a handler object implements its Handlemessage method, in Handlemessage
Provide the corresponding processing method after receiving the message, here does not handler the use of detailed explanation, before looking at Ben Boven, the reader should first grasp the basic use of handler, I here mainly in-depth description of handler internal mechanism

Now we have a problem first, we use Mythreadhandler.sendemptymessage (0); Send a Message object, so how does handler receive the message object and handle it? Let me draw a data structure diagram:

From this figure we can see that after calling Sendemptymessage, the message object is placed in a MessageQueue queue belonging to a Looper object, each Looper object passing Threadlocal.set ( New Looper ()) is bound to a thread, The thread that the Looper object belongs to loops through the Looper.loop method, reads the message object from the MessageQueue queue, and puts the message object handler processing, calling handler's DispatchMessage method.

Now let's take a look at the basic implementation code that uses handler:

Create a new handler in the main thread
Normalhandler = new Handler () {
public void Handlemessage (Android.os.Message msg) {
Btnsendmsg2normalhandler.settext ("Normalhandler");
LOG.D (Constant.tag, Messageformat.format ("Thread[{0}]--normalhandler handlemessage run ...", Thread.currentThread ()
. GetName ()));
}
};

...
Send Message to Hanlder
Mythreadhandler.sendemptymessage (0);

You are now well aware of the process of sendemptymessage to Handlemessage, On the way through the Looper.messagequeue queue, transferred by the Looper on the thread to deal with, this is an asynchronous process, of course, Looper is located in the same thread can be sendemptymessage.

See above you may still be puzzled, then what to Looper, with we want to use of handler and what bird relationship?

I have always emphasized the use of handler in the main thread, why do you say so, because you in the new thread of your own to build a handler as simple as before, program execution will be error:

Java.lang.RuntimeException:Can ' t create handler inside thread that have not called looper.prepare ()
At Android.os.handler.<init> (handler.java:121)
At Com.cao.android.demos.handles.handletestactivity$mythread$1.<init> (handletestactivity.java:86)
At Com.cao.android.demos.handles.handletestactivity$mythread.run (handletestactivity.java:86)

Why is there no error in the main thread, and it is reported in the newly-seen threads? Very simple, because the main thread it has established looper, you can open the Activitythread source to see:

public static final void main (string[] args) {
Samplingprofilerintegration.start ();

Process.setargv0 ("<pre-initialized>");

Looper.preparemainlooper ();

Activitythread thread = new Activitythread ();
Thread.attach (FALSE);

Looper.loop ();

if (process.supportsprocesses ()) {
throw new RuntimeException ("Main thread loop unexpectedly exited");
}

Thread.detach ();
String name = (thread.minitialapplication! = null)
? Thread.mInitialApplication.getPackageName ()
: "<unknown>";
SLOG.I (TAG, "Main thread of" + name + "is now exiting");
}

In the main function it has done this thing, why call Looper.preparemainlooper (); Looper.loop (); we can take a look inside. A new Looper object is created in the Preparemainlooper method and is bound to the current process. In the Looper.loop method, the thread establishes a message loop mechanism that loops through the MessageQueue to get the message object, calling Msg.target.dispatchMessage (msg); The processing Msg.target is set in Mythreadhandler.sendemptymessage (0), because multiple hander can be built in a THEAD, With the msg.target to ensure that each msg in the MessageQueue is disposed of by the handler that sent the message, how does handler relate to Looper, and in the handler constructor there is a piece of code:

Mlooper = Looper.mylooper ();
if (Mlooper = = null) {
throw New RuntimeException (
"Can ' t create handler inside thread that have not called looper.prepare ()");
}
Mqueue = Mlooper.mqueue;

When you create a new handler, you need to set the Mlooper member, Looper.mylooper is the Looper object that gets the bindings from the current thread:

public static final Looper Mylooper () {
Return (Looper) sthreadlocal.get ();
}

If the Looper object is not created, it throws an exception to the "can ' t create handler inside thread that have not called looper.prepare ()"
This is consistent with what I said earlier. So we're going to create a handler in a new thread that needs to be written like this:

Class MyThread extends Thread {

public void Run () {
LOG.D (Constant.tag, Messageformat.format ("thread[{0}]--run ...", Thread
. CurrentThread (). GetName ()));
Create a new handler in other threads
Looper.prepare ();//Create the Looper object for the thread to receive the message, which is not Looper in the non-main thread, so be sure to use prepare () to create a Looper before creating handler
Mythreadhandler = new Handler () {
public void Handlemessage (Android.os.Message msg) {
LOG.D (Constant.tag, Messageformat.format ("Thread[{0}]--mythreadhandler handlemessage run ...", Thread
. CurrentThread (). GetName ()));
}
};
Looper.mylooper (). loop ();//Create a message loop that does not exit
}
}

Now, you should know something about handler's mechanism, and if you have any questions, please ask in the comments.

Handler using the main thread in other threads Looper

I told you before. To create a new handler in a newer thread, you need to call Looper.prepare (); Another way is to use Looper in the main thread, so you don't have to create a new Looper object:

Threadmainloophandler =new Handler (Looper.getmainlooper ()) {
public void Handlemessage (Android.os.Message msg) {
LOG.D (Constant.tag, Messageformat.format ("Thread[{0}]--threadmainloophandler handlemessage run ...", Thread
. CurrentThread (). GetName ()));
}
The Handlemessage method will be executed in the Mainthread
};

Be careful not to do too much at Handlemessage because it executes in the main thread, which affects the main thread to perform UI update operations.

Using the Message.callback callback

public void DispatchMessage (Message msg) {
if (msg.callback! = null) {
Handlecallback (msg);
} else {
if (mcallback! = null) {
if (Mcallback.handlemessage (msg)) {
Return
}
}
Handlemessage (msg);
}
}
As you can see from the dispatchmessage definition, if the message object comes with a callback object, Handler does not execute the Handlemessage method but executes the run method defined in Message.callback, and of course callback is executed in the thread bound by handler associated Looper. In fact Handler.post (Runnable R) method is to add R to a msg.callback, that is to say, the following two ways of writing, there is no difference:

1. Using Message.callback

[Java]View Plaincopy
    1. message msg = message.obtain (Mythreadhandler,new runnable ()  {  
    2.       
    3.      @Override   
    4.     public void run ()  {   
    5. &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;LOG.D (Constant.tag,  messageformat.format ( "Thread[{0}]--mythreadhandler.message.callback.run",   
    6.                  thread.currentthread (). GetName ());    
    7.      }  
    8. });   
    9. mythreadhandler.sendmessage (msg);   

2. Using Handler.post

[Java]View Plaincopy
  1. Mythreadhandler.post (new Runnable () {
  2. @Override
  3. public Void Run () {
  4. LOG.D (Constant.tag, Messageformat.format ("Thread[{0}]--mythreadhandler.message.callback.run",
  5. Thread.CurrentThread (). GetName ());
  6. }
  7. });

Note: For the handler mechanism-related tests, I wrote a test class:

http://download.csdn.net/source/3275970

3.Handler effect on activity finish.

In the process of development encountered a difficult problem, Call the Activity.finish function acitivity does not perform the ondestory function of the life cycle, after looking for half a day because there is a handler member because it has a delay message is not processed, call activity.finish,activity will not immediately de Story, so remember to clean up the handle before ativity finish, so the activity will go smoothly destory

Advanced Android handler mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.