Android's message mechanism is mainly handler operating mechanism, and the handler mechanism, but also need and MessageQueue and looper combination. MessageQueue the message queue, although called a queue, but its internal structure is not composed of queues, but the use of a single-linked list to store messages. MessageQueue is only responsible for storing messages, not processing messages (this refers to the rotation of the message), Looper just made up for the vacancy. I know that when handler is created, the default is for us to create a Looper object, so how to get the current looper, here is the concept of a theadlocal, theadlocal can easily get the current use of looper.
Use of handler:
Handler There are two main ways to use it: ( 1 ) dispatch messages and runnable object and executes at a point in time. ( 2 in turn, the behavior that belongs to different threads is stored.
The thread is not associated with the Looper by default. In the thread, we can invoke the Prepare method to start a message loop and call the Loop method to notify Looper to process the message until the end. Looper provides a number of static methods to interact with threads and message queues. A thread allows a maximum of one Looperto be created.
The following is a way to use handler in threads as described in the SDK documentation:
Class Looperthread extends Thread {public Handler Mhandler; public void Run () { looper.prepare (); Mhandler = new Handler () {public void Handlemessage (Message msg) { //process incoming messages here } }; Looper.loop (); }
Note here that the official example is associated with looper, so what happens if we don't associate Looper?
mrunnable = new Runnable () { @Override public void Run () { //TODO auto-generated method stub String s = Mhandler.getlooper (). GetThread (). GetName (); LOG.E ("handler", s); Mhandler.postdelayed (mrunnable, +); }; Thread T = new Thread (mrunnable, "thread"); T.start ();
Operation Result:
Error/handler (1630): Main, we can find that we have created a thread called "thread", the disease sends a message through handler, the handler we created is automatically associated with the looper of the UI thread.
< Span style= "LINE-HEIGHT:26PX; font-size:10pt; Font-family: Song body "> So, can you define the handler handler looper
mrunnable = new Runnable () { @Override public void Run () { //TODO auto-generated method stub Looper.prepare (); Mhandler = new Handler (Looper.mylooper ()); String s = Mhandler.getlooper (). GetThread (). GetName (); LOG.E ("handler", s); Mhandler = new Handler (Looper.getmainlooper ()); s = Mhandler.getlooper (). GetThread (). GetName (); LOG.E ("handler", s); }; Thread T = new Thread (mrunnable, "subthread"); T.start ();
Operation Result:
Error/handler (4049): Subthread
error/Handler(4049): Main
But our Android provides us with a THEAD class that contains Looper, Handlerthread Handlerthread brought a lopper,
Handlerthread=new handlerthread ("Handlerthead"); Handlerthread.start (); Handler=new handler (Handlerthread.getlooper ()); Handler.post (New Runnable () { @Override public void Run () { String s=handler.getlooper (). GetThread (). GetName (); LOG.D ("Test", s); } );
Note:Androidthink of operating in non-threadingUIThe interface is not secure, so it is forbidden to modify it in other threadsUIinterface. There are two ways to solve this, one is by defining it in the main thread.Handlerupdate the interface, the second is to directly call the modifiedViewof thepostinvalidatemethod refreshes a singleView.
In fact, the above description is inaccurate, in fact, when the activity first executes, it is possible to directly update the main thread data on the child thread, the condition is not to execute thread.sleep (),
What is the reason?
1. When the activity is just started oncreate inside this time the Onresume method has not been executed, because the UI is updated in the thread to call Viewparent.invalidatechild () The Uithread method checks whether the current thread is a uithread and can be updated (Viewparent is an interface class whose implementation is Viewrootimpl;invalidatechild () method call Checkthread () method to check if the thread is the main path). Viewrootimp is initialized in the Onresume method, so as long as the UI is updated before Viewrootimpl is created (the thread is created in the OnCreate method and executed, and the viewrootimp is not initialized at this time), You can escape the Checkthread () check and update the UI.
2.--> just started, immediately in the non-UI thread update-no error (Onresume has not been executed)
---> Hibernate after 2s, update —————— > Error
Finally, put a picture on it.
After analyzing the process of the Android messaging mechanism, we then understand some important concepts separately. Mainly from the following aspects to enhance understanding, handler,messagequeue,looper and threadloacal.
Android Development Handler Source analysis