Android handler message logoff mechanism Principle

Source: Internet
Author: User

Speaking of handler in Android, let's first talk about the mechanism and principle of handler.

1. Handler mechanism Principle

 

Handler:It is mainly used to process sending and receiving messages. It is used to add messages to a specific logoff message queue and distribute and process messages in the queue. You can specify a logoff object when constructing a handler,Through the handler object, we can encapsulate the message object, and then add the message object to messagequeue through sendmessage (MSG); When messagequeue loops to this message, the handlemessage () method of the handler object corresponding to the message object will be called to process it.

When the main thread uses handler = new handler (); that is, when the default constructor is used to construct handler, It is the logoff object of the main thread by default, the handler constructed in this way belongs to the main thread, that is, the handler and logoff are bound together. If the logoff object of A New thread is specified during handler construction, the handler object belongs to the subthread.

Every android application runs in a Dalvik virtual machine process. When a process starts, a main thread (mainthread) is started. The main thread is responsible for processing UI-related events, therefore, the main thread is often called the UI thread. Because Android uses a single-threaded UI model, you can only operate the UI elements in the main thread. If you operate the UI directly in a non-UI thread, an error is reported. Handler needs to be initialized in the main thread. Why do you want to say this? Because you simply create a handler in your new thread, an error will be reported during program execution:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()    atandroid.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 this error not reported in the main thread, but in the self-created thread? It is very simple, because the main thread has already created a looper, because the main thread has its own Looper object and message object by default. Non-main threads do not have their own Looper by default, and they need to create their own Looper: through logoff. prepare creates a logoff object and
Logoff. Loop () creates a message loop queue;You can create a handler object in a new thread (non-main thread) in either of the following ways:

(1) create a logoff object using the logoff. Prepare () method before handler is created.

Class mythread extends thread {public void run () {log. D (constant. tag, messageformat. format ("thread [{0}] -- run... ", thread. currentthread (). getname (); // create a handler logoff in a non-main thread. prepare (); // create a logoff object for this thread to receive messages. There is no logoff in a non-main thread. Therefore, you must use prepare () before creating a handler () create a looper 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 ();} logoff. mylogoff (). loop (); // creates a message loop and the thread will not exit };}}

 

(2) Use the logoff object of the main thread, because each main thread has created its own logoff object by default.

Class mythread extends thread {public void run () {log. D (constant. tag, messageformat. format ("thread [{0}] -- run... ", thread. currentthread (). getname (); handler threadmainloophandler = new handler (loler. getmainlomessage () {// The handlemessage method will execute public void handlemessage (Android. OS. message MSG) {log. D (constant. tag, messageformat. format ("thread [{0}] -- threadmainloophandler handlemessage run... ", thread. currentthread (). getname ()));}};}}

(3) Summary

The main difference between (1) and (2) is: (1) the handler object belongs to the subthread, and its handlemessage is executed in the subthread, and (2) the handler belongs to the main thread, because it and the Logoff of the main thread. getmainlooper () objects are bound together. Therefore, do not perform complex and time-consuming operations such as network and IO operations in the handlemessage method. Otherwise, the UI thread will be blocked, resulting in ANR.
 

After being familiar with the principles of handler and logoff mechanisms, it is easier to understand how to Implement Asynchronous processing through handler, first, let's look at a similar calculator function through handler and runnable:

2. Handler + runable (you can implement functions similar to a counter. Note the difference between handler and runable 3. Is it synchronous or asynchronous ?)

The handler object is automatically bound to the Message Queue by default during initialization. The post method can be used to send the runnable object to the message queue and execute the run method in different runnable objects in order according to the queue mechanism.

1. public class handleractivity extends activity {2. /** called when the activity is first created. */3. // declare two button controls 4. private button startbutton = NULL; 5. private button endbutton = NULL; 6. @ override 7. public void oncreate (bundle savedinstancestate) {8. super. oncreate (savedinstancestate); 9. setcontentview (R. layout. main); 10. // obtain the object representing the control according to the Control ID. No listener is set for the two buttons 11. startbutton = (button) findviewbyid (R. id. startbutton); 12. startbutton. setonclicklistener (New startbuttonlistener (); 13. endbutton = (button) findviewbyid (R. id. endbutton); 14. endbutton. setonclicklistener (New endbuttonlistener (); 15. 16 .} 17. class startbuttonlistener implements onclicklistener {18. 19. @ override 20. public void onclick (view v) {21. // call the post method of handler and add the thread object to be executed to the queue. 22. handler. post (updatethread); 23 .} 24. 25 .} 26. 27. class endbuttonlistener implements onclicklistener {28. 29. @ override 30. public void onclick (view v) {31. handler. removecallbacks (updatethread); 32 .} 33. 34 .} 35. // create a handler object 36. handler handler = new handler (); 37. // write the operation to be executed in the run method of the thread object 38. runnable updatethread = new runnable () {39. 40. @ override 41. public void run () {42. system. out. println ("updatethread"); 43. // execute postdelayed or POST method 44 Within the run method. handler. postdelayed (updatethread, 3000); 45 .} 46. 47 .}; 48 .}
3. Two asynchronous processing methods through handler 3.1 thread + handler message

 

Thread + handler message: When the thread is enabled, message is used to transmit information between the background (sub) thread and the UI main thread. After the UI thread receives the information, it updates the UI. 

 

Public class handlertestactivity extends activity {private progressbar bar = NULL; private Boolean isrunning = false;/* we create a handler for this acivity to communicate with the background program, simply, once a message is received, the progress of progressbar is increased by 5. * // * Step 1: Create a handler and use handlemessage () to show how the UI processes the received message, in this example, the content of MSG is not analyzed. */handler = new handler () {public void handlemessage (Message MSG) {bar. incrementprogressby (5) ;}}; protected void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. chapter_15_test1); bar = (progressbar) findviewbyid (R. id. c15_progress);}/* on Start is called when the UI is initialized and displayed */protected void onstart () {super. onstart (); Bar. setprogress (0);/* Step 2: Create a background thread for processing. Use a thread. The content of run () is the content processed by the thread in parallel, thread is the implements of runnable */thread background = new thread (New runnable () {public void run () {try {for (INT I = 0; I <20 & isrunning; I ++) {thread. sleep (1000);/* Step 2.1: send the message to the queue. The obtainmessage () parameter is used to provide a new message. In this example, no parameter is specified, when handlemessage is received by handler in the queue, handlemessage () is used for processing */handler. sendmessage (handler. obtainmessage () ;}} catch (throwable t) {// jest end the thread }}); isrunning = true;/* Step 3: Start the thread */background. start ();}/* onstop is called when the UI stops displaying. For example, if we press the return key */protected void onstop () {super. onstop (); isrunning = false ;}}
3.2 handler and multithreading are implemented using handler post and runnable (note the difference with 2)

Although the handler POST method sends a class object that implements the runnable interface, it does not create a new thread, but executes the run method in the object. That is to say, the operation in the entire run is in the same thread as the main thread.

This does not seem to affect those simple operations. However, for a time-consuming operation, it takes a long time to execute after it is added to the message queue, so that other operations in the same thread cannot continue to execute, then there will be "false dead ". To solve this problem, we need to bind the handler to a message queue with a newly enabled thread, and process the passed runnable object and message in the Message Queue with another thread. The SDK documentation also provides instructions:

1. public class handlertest2 extends activity {2. 3. @ override 4. protected void oncreate (bundle savedinstancestate) {5. // todo auto-generated method stub 6. super. oncreate (savedinstancestate); 7. setcontentview (R. layout. main); 8. // print the ID of the current thread 9. system. out. println ("activity -->" + thread. currentthread (). GETID (); 10.11. // generate a handlerthread object 12. handlerthread = new handlerthread ("Ha Ndler_thread "); 13. // before using the getlooper () method of handlerthread, you must call start () of the class and start a new thread. 14. handlerthread. start (); 15. // pass the looper obtained by handlerthread to the handler object, that is, the lo in another thread replaces the default bound Message Queue during handler initialization to process messages. 16. // customize handler17. myhandler = new myhandler (handlerthread. getlooper (); 18. message MSG = myhandler. obtainmessage (); 19. // send MSG to the target object. The so-called target object is the handler object that generates the MSG object 20. bundle B = new bundle (); 21. b. putint ("Age", 20); 22. b. putstring ("name", "Jhon"); 23. MSG. setdata (B); 24. MSG. sendtotarget (); // send MSG to myhandler25.} 26. 27. // customize the handler Class 28. class myhandler extends handler {29. public myhandler () {30. 31 .} 32. 33. public myhandler (low.logoff) {34. super (logoff); 35 .} 36. // here the handlemessage will be executed in the sub-thread handlerthread rather than in the main thread 37. @ override 38. public void handlemessage (Message MSG) {39. bundle B = MSG. getdata (); 40. int age = B. getint ("Age"); 41. string name = B. getstring ("name"); 42. system. out. println ("Age is" + age + ", name is" + name); 43. system. out. println ("handler --->" + thread. currentthread (). GETID (); system. out. println ("handlermessage"); 44 .} 45 .} 46 .}

 

 

 

 

Related Article

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.