Android technology 21: Android asynchronous message processing thread, android asynchronous
Android asynchronous Message processing thread, which is always in an infinite loop, reads messages from the Message Queue each time, then calls back the Message processing method, and processes messages in HandlerMessage of Handler. If the message queue is empty, the thread will be suspended, and the thread will be awakened when a message in the message queue comes in.
1. Android asynchronous thread Internal Structure
There is one or more Handler objects in the thread. An external program sends an asynchronous Message to the thread through the Handler object, and the Message is transmitted to the Message Queue object through the Handler, each thread contains only one message queue object. The main execution function of the thread reads messages from the message queue and calls back the Handler object method handlerMessage ().
2. Thread Local Storage
The programmer creates a Message Queue object for the thread through the logoff Static Method prepare.
Static final ThreadLocal <Looper> sThreadLocal = new ThreadLocal <lolocal> ();
1 private static void prepare(boolean quitAllowed) {2 if (sThreadLocal.get() != null) {3 throw new RuntimeException("Only one Looper may be created per thread");4 }5 sThreadLocal.set(new Looper(quitAllowed));6 }
The local thread object TLS, Which is set through the set method of sThreadLocal.
3. Logoff
The role of the logoff object is to create a message queue, and to enable the current thread to provide a static method loop () to enter the loop and read messages from the message queue.
1 private Looper(boolean quitAllowed) {2 mQueue = new MessageQueue(quitAllowed);3 mRun = true;4 mThread = Thread.currentThread();5 }
When you need to change a Thread to an asynchronous message processing Thread, you should first call logoff in the run () function of the Thread class. prepare () creates a Message Queue object for the thread. then call logoff. loop () enables the current thread to enter the message processing cycle.
1 public static void loop() { 2 final Looper me = myLooper(); 3 if (me == null) { 4 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); 5 } 6 final MessageQueue queue = me.mQueue; 7 8 // Make sure the identity of this thread is that of the local process, 9 // and keep track of what that identity token actually is.10 Binder.clearCallingIdentity();11 final long ident = Binder.clearCallingIdentity();12 13 for (;;) {14 Message msg = queue.next(); // might block15 if (msg == null) {16 // No message indicates that the message queue is quitting.17 return;18 }19 20 // This must be in a local variable, in case a UI event sets the logger21 Printer logging = me.mLogging;22 if (logging != null) {23 logging.println(">>>>> Dispatching to " + msg.target + " " +24 msg.callback + ": " + msg.what);25 }26 27 msg.target.dispatchMessage(msg);28 29 if (logging != null) {30 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);31 }32 33 // Make sure that during the course of dispatching the34 // identity of the thread wasn't corrupted.35 final long newIdent = Binder.clearCallingIdentity();36 if (ident != newIdent) {37 Log.wtf(TAG, "Thread identity changed from 0x"38 + Long.toHexString(ident) + " to 0x"39 + Long.toHexString(newIdent) + " while dispatching to "40 + msg.target.getClass().getName() + " "41 + msg.callback + " what=" + msg.what);42 }43 44 msg.recycle();45 }
4. Message Queue
From the above we can see that through queue. next (), read a Message, but there is no Message Queue object in the Framework. The two main functions of Message Queue read the Message and add the Message, namely next () and enquenceMessage (). but the actual implementation is not implemented in the Framework layer but in the C code through JNI.
1 private native static int nativeInit();2 private native static void nativeDestroy(int ptr);3 private native static void nativePollOnce(int ptr, int timeoutMillis);4 private native static void nativeWake(int ptr);
5. Handler
Before constructing a Handler object, you must have performed logoff. prepare (), in logoff. in the loop () function, different messages correspond to different Handler objects, and different handlerMessage () functions are called back.
Java or android asynchronous implementation can only use multithreading. Is there any other way?
In android, AsyncQueryHandler and AsyncTask are both used for asynchronous message transmission, but they are essentially multithreading. However, Android Can Help You encapsulate and conveniently call them. Hope to help you!
Question about how Android gets the result after the thread is executed
In fact, Google has long been aware of this problem. There is a send method in Message. As follows:
Message msg = mhandler. obtainMessage (MSG_UPDATE, imgIndex, 0 );
Mhandler. sendMessage (msg );
Then rewrite the handlerMessage method of handler as follows:
Private Handler mhandler = new Handler (){
@ Override
Public void handleMessage (Message msg ){
If (msg. what = MSG_UPDATE ){
// The operation you want...
}
}
};
This is basically the case!