Android message mechanism source code analysis

We know that when the application starts, android will first start a main thread, the main thread manages the ui control, and distributes events. When editing files, you should operate in the sub-thread, because there are ui updates, and the android main thread is not thread-safe. It is dangerous to update the interface in the sub-thread, and it must be executed in the main thread. At this time Lead out Handler, Handler runs on the main thread, and he and the child thread pass data through the message object.

Message class

Message class : the carrier used to carry data
 public int what ; // identify
 public int arg1 ; // carry int type data
 public int arg2 ; // carry int type data
 public Object obj ; // carry any object data
 long when ; / / Save the time point to be processed
 Handler target ; // Handler
 Runnable callback for processing messages ; // Callback object for processing messages
 Message next ;// Used to save the next message referenced ( to form a linked list )
 private static Message sPool ; // The pool for storing processed messages // Reuse when Message objects are needed
Message .obtain();//Obtain an empty message object from the message pool

illustrate:

1. When we want to obtain an empty message object, it is better to use the Message.obtain() method to get the message from the message pool instead of its constructor, so that the message object can be reused better to save memory.

2. If the Message needs to carry int data, you can use its arg attribute

3. The target in the Message is the handler for processing the message

4. what is the identification information category


Handler class

sendMessage ( Message msg ) ;
 sendEmptyMessage ( int what ) ;
 sendMessageDelayed ( Message msg , long delayMillis )
 sendMessageAtTime ( msg , SystemClock.uptimeMillis() + delayMillis ) ; // current time + delay time
 private boolean enqueueMessage ( MessageQueue queue msage , Message long uptimeMillis) {
     msg .target = this ; // process the messageHandler is the handler
 for sending messages if (mAsynchronous) {
         msg . setAsynchronous ( true ) ;
 }
     return queue .enqueueMessage( msg , uptimeMillis ) ; // Add the message to the message queue
 }        

public final void removeMessages ( int what) {   // Remove unprocessed messages in the queue
     mQueue.removeMessages( this , what , null ) ;
 }

public void dispatchMessage ( Message msg ) {
     if ( msg .callback != null ) { // If there is a callback handler inside the message , hand it over to
 handleCallback( msg ) directly ;
 } else {
         if (mCallback != null ) {
   / / If there is a callback processor inside the Handler , hand it over to it for processing . If it returns true , it will end , otherwise continue
 if (mCallback.handleMessage( msg )) {
                 return            
              ;
            }
        }
        handleMessage ( msg ) ; // call the callback method of
 Handler to process }    
}
have to be aware of is:

1. The handler can send messages in any thread, and these messages will be added to the MessageQueue

2. The handler actually processes messages in the thread associated with the looper. Of course, the main thread is also a looper thread


MessageQueue

enqueueMessage(Message msg, long when) {
    msg.when = when ; // Save the time when the message is processed on msg
 // Save the msg object to a suitable position in the
 mMessages list nativeWake(mPtr) ; // Wake up the program in the waiting state
 // Not pass wait() , but through C/C++ code , without blocking the main thread
 }
    
        

Message next() { //从消息队列中取出需要处理的消息, 如果没有进入等待状态(没有阻塞主线程)

}

Looper

looper线程的创建

public class LooperThread extends Thread {
    @Override
    public void run() {
        // 将当前线程初始化为Looper线程
        Looper.prepare();

        ...

        // 开始循环处理消息队列
        Looper.loop();
    }
}

looper的一些属性

public class Looper {
    private static final ThreadLocal sThreadLocal = new ThreadLocal();// 每个线程中的Looper对象其实是一个ThreadLocal
    
    final MessageQueue mQueue;// Looper内的消息队列
    
    Thread mThread;// 当前线程


private Looper () { // Create a message queue in the
 Looper object, and the thread it belongs to mQueue = new MessageQueue () ; mRun = true ;
 mThread = Thread . currentThread () ;
 }    
        


Create looper object method

public static final void prepare() {
    if (sThreadLocal.get() != null) {
       
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper());
}

static void loop() {
    final MessageQueue queue = me.mQueue; //拿到消息队列
    Message msg = queue.next();// might block  从队列中取出当前需要处理的消息

}
//message对象交给handler分发处理
msg.target.dispatchMessage(msg);

msg.recycle(); //回收处理过消息: 清理内部数据, 并添加为消息池的第一个消息

这样我们就把消息队列中的几个重要的对象简单的过了一边。

Guess you like

Origin blog.csdn.net/yuanzhihui123/article/details/50558367