The UI thread for each app in Android is protected from time-consuming operations in the UI thread, and other sub-threads do not work directly with the UI.
In order to achieve this goal Android designed the handler Looper this system framework.
The source tracking process is first explained when using handler in the main thread.
Normally define a handler in the activity's OnCreate function, in which case it is the default main thread handler, and the Handlemessage () function of the class is replicated.
Private Final New Handler () { @Override publicvoid handlemessage (Message msg) { ...;} }
Here new a handler class, followed into the system code
106 /**107 * Default Constructor Associates This handlerwith the {@link Looper} For the108 * thread.109 *110 * If The This thread does not has a looper, this handler won ' t is able to re Ceive messages111 * so a exception is thrown.112*/113 public Handler ( {This (nullfalse); + + }
188 PublicHandler (Callback Callback,Booleanasync) {189if(find_potential_leaks) {190Finalclass<?extendsHandler> Klass =getclass ();191if((Klass.isanonymousclass () | | | klass.ismemberclass () | | klass.islocalclass ()) &&192 (Klass.getmo Difiers () & modifier.static) = = 0) {193 LOG.W (TAG, "the following Handler class should be static or leaks might occur:" +194klass.getcanonicalname ());195 }196 }197198 Mlooper =Looper.mylooper ();199if(Mlooper = =NULL) {200Throw NewRuntimeException (201 "Can ' t create handler inside thread that have not called looper.prepare ()");202 }203 Mqueue =Mlooper.mqueue;204 Mcallback =callback;205 masynchronous =Async;206}
Finally, you need to assign a value to the three variables of mqueue;mcallback;masynchronous.
Note here Mlooper = Looper.mylooper (); Initialization of the Mlooper. And here we go into the Looper class.
191 public static @Nullable Looper mylooper () {192 return Sthreadlocal.get (); 193 }
/ / sthreadlocal.get () would return null unless you ' ve called prepare (). The staticfinalnew threadlocal<looper> ();
private static void Prepare (boolean quitallowed) { if (sthreadlocal.get ()! = Null ) { 94 throw new runtimeexception (" Only one Looper could be created per thread "95} sthreadlocal.set (new
Looper (quitallowed));
97} 98
Finally, new Looper (quitallowed) creates an Looper object in the current thread (so it can be seen from here that Looper belongs to the current thread).
Normally in our own new thread we need to call Looper.prepare (); The statement to new a Looper object for the current thread. However, it is not required for Looper created in the UI thread because it is already written when the UI thread is initialized.
This function is called when the normal UI thread is initialized preparemainlooper.
99/**Initialize The current thread as a looper, marking it as an101 * application ' s main looper. The main looper for your application102 * are created by the Android environment, so you should never need103 * to Call this function yourself. See also: {@link#prepare ()}104*/105 Public Static voidPreparemainlooper () {106 Prepare (false);107synchronized(Looper.class) {108if(Smainlooper! =NULL) {109Throw NewIllegalStateException ("The main Looper has already been prepared.");110 }111 Smainlooper =Mylooper ();112 }113}
For a generic child thread, you need to continue calling Looper.loop to start the loop loop for message sending.
The same looper for the UI thread has been called in the initialization process as well.
128 Public Static voidLoop () {129FinalLooper me =Mylooper ();130if(Me = =NULL) {131Throw NewRuntimeException ("No Looper; Looper.prepare () wasn ' t called on the This thread. ");132 }133FinalMessageQueue queue =Me.mqueue, ........142 for (;;) {143 Message msg = Queue.next ();//might block144if(msg = =NULL) {145//No message indicates that the message queue is quitting.146return;147} ..... 158 msg.target.dispatchMessage (MSG);
You can actually see the message loop mechanism in this loop () function. In a dead loop for (;;) The messager is constantly fetched from the queue Message Queuing, if there is no block waiting for the next messager on that port.
Message distribution is placed in the targe of a message after it has been fetched.
The target here is actually the handler that was passed in when the message was encapsulated, so it can be seen from here that the last message is processed by calling Handlemessage () in the same thread that handler passed in.
Member variables for Message.java:
Public Final classMessageImplementsparcelable { Public intwhat ; Public intarg1; Public intarg2; PublicObject obj; PublicMessenger ReplyTo; Public intSendinguid =-1; /* Package*/ Static Final intFlag_in_use = 1 << 0; /**If Set message is asynchronous*/ /* Package*/ Static Final intflag_asynchronous = 1 << 1; /**Flags to clear in the CopyFrom method*/ /* Package*/ Static Final intFlags_to_clear_on_copy_from =Flag_in_use; /* Package*/ intflags; /* Package*/ LongWhen ; /* Package*/Bundle data; /* Package*/Handler Target/* Package*/Runnable callback; //sometimes we store linked lists of these things /* Package*/Message Next;
。。。。
Android in about handler Looper understanding