Process Summary
- Looper.prepare (): Saves an Looper instance in this thread, and then holds a MessageQueue object in the instance, because Looper.prepare () can only be called once in a thread, So MessageQueue will only exist in one thread.
- Looper.loop (): Poll MessageQueue, Callback Msg.target.dispatchMessage (msg) method.
- Handler constructor method: Gets the Looper instance that is saved in the current thread, and then associates with MessageQueue in the Looper instance.
- Handler SendMessage (): Assigns the target of MSG to handler itself, and then joins the MessageQueue.
- Override Handlemessage (): Is the method that Msg.target.dispatchMessage (msg) eventually calls.
TIP: In the activity's startup code, the Looper.prepare () and Looper.loop () methods have been called in the current UI thread. Call Looper.prepare () and Looper.loop () to create handler without the display
Observer pattern
Looper
Create a MessageQueue, poll MessageQueue
- Construction Method
- Prepare ()
- Loop ()
- Looper method must be run after the Prepare method
- polling, no-, blocking, with Msg.target.dispatchMessage (msg);
- role
- binding when a front-line, with only one looper instance and MessageQueue, polls and notifies
Handler
Message Creator, asynchronous distribution
public Handler () {This (null, false); } public Handler (Callback Callback, Boolean async) {if (Find_potential_leaks) {final class<? e Xtends handler> klass = GetClass (); if (Klass.isanonymousclass () | | klass.ismemberclass () | | klass.islocalclass ()) && (klass.get Modifiers () & modifier.static) = = 0) {LOG.W (TAG, "the following Handler class should be STATIC or Le AKS might occur: "+ klass.getcanonicalname ()); }} Mlooper = Looper.mylooper (); if (Mlooper = = null) {throw new RuntimeException ("Can ' t create handler inside thread that Have not called Looper.prepare () "); } mqueue = Mlooper.mqueue; Mcallback = callback; masynchronous = async; }
- Mlooper = Looper.mylooper (); Get Looper
- Mqueue = Mlooper.mqueue; get MessageQueue
Public Final Boolean sendMessage (Message msg) { return sendmessagedelayed (msg, 0);
Private Boolean enqueuemessage (MessageQueue queue, Message msg, long Uptimemillis) { msg.target = this; if (masynchronous) { msg.setasynchronous (true); } Return Queue.enqueuemessage (msg, uptimemillis); }
- Msg.target = this; = = Msg.target.dispatchMessage (msg); Handler messages will eventually be saved to the message queue.
Messagedispathmessage
public void DispatchMessage (Message msg) { if (msg.callback! = null) { handlecallback (msg); } else { if ( Mcallback! = null) { if (Mcallback.handlemessage (msg)) { return; } } Handlemessage (msg); } }
Because the final callback of the message is controlled by us, we are the replication Handlemessage method when creating the handler, and then the message is processed according to the Msg.what.
Private Handler Mhandler = new Handler () {public void Handlemessage (android.os.Message msg) { switch ( Msg.what) {case value: Break ; Default: Break;};} ;
- public int What: variable that defines what this message does
- Public Object obj: variable that defines the information data passed by this message, passing information through it
- public int arg1: variable that is used when passing some integer data
- public int ARG2: variable that is used when passing some integer data
- Public Handler gettarget (): Normal method, gets the Handler object that operates this message.
Complete scheduling information
- {@link #post}, {@link #postAtTime (Runnable, Long)},
- {@link #postDelayed}, {@link #sendEmptyMessage},
- {@link #sendMessage}, {@link #sendMessageAtTime}, and
- {@link #sendMessageDelayed} methods. The <em>post</em> versions allow
Handler Post
Mhandler.post (New Runnable () { @Override public Void Run () { log.e ("TAG", Thread.CurrentThread (). GetName ()); Mtxt.settext ("Yoxi"); } );
Runnable did not create a thread, but sent a message
Public Final Boolean post (Runnable R) { return sendmessagedelayed (Getpostmessage (R), 0); }
private static Message Getpostmessage (Runnable r) { Message M = Message.obtain (); M.callback = R; return m; }
In Getpostmessage, we get a message object and assign the Runable object we created as the callback property to this message.
Note:
- Generates a message object that can be new or use Message.obtain ()
- Message internally maintains a message pool for reuse of message, using the Message.obtain () method to avoid reallocating memory using new.
- If your message only needs to carry simple int information, prioritize using MESSAGE.ARG1 and message.arg2 to pass information, which is more memory-saving than using bundles
- Use Message.what to identify information to handle messages in different ways
If it is not NULL, then the callback callback is executed, which is our Runnable object.
Problem
1, using handler is asynchronous, will it create a new thread? No
Is 2,handler in the mainline range? Typically within the main thread, but you can also create handler in a child thread
3,handler the Post and SendMessage methods, using a queue of uneasiness is two? One
4, create a handler in the sub-thread, and then SendMessage what happens? Will crash
5, the child thread establishes handler, constructs the time comfortable to enter the main thread the Looper? Yes
Android handler mechanism source parsing "asynchronous callback"