Android知识程序员Android技术知识

Android线程切换之谜

2017-08-04  本文已影响0人  一只小松

之前有写过一篇文章 记一次Handler的优化 ,当时并未详细的讲解Handler的线程切换功能。遂写下这篇文章,对其进行补充。
那么这一篇不得的提及到另外一个重要的类Looper。提取了Looper类中几段重要之处进行分析,其实线程切换真的很简单。

public final class Looper{
......
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static void loop(){
    // 看方法上的注释也能明白为何线程能够切换,因为handler发送的消息在创建handler关联的Looper对象所在线程被消费
    final Looper me = myLooper();// 获取当前线程对应的Looper对象
    if(me == null){
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;// 获取Looper对象中的消息队列
    // Make sure the identity of this thread is that of the local process,
    // and keep track of what that identity token actually is.
    Binder.clearCallingIdentity();
    final long ident=Binder.clearCallingIdentity();
    for(;;){
        Message msg = queue.next();// might block 阻塞获取Looper队列中的消息
        if(msg == null){
            // No message indicates that the message queue is quitting.
            return;
        }
        // This must be in a local variable, in case a UI event sets the logger
        final Printer logging = me.mLogging;
        if(logging != null){
            logging.println(">>>>> Dispatching to "+msg.target+" "+
            msg.callback+": "+msg.what);
        }
        final longtraceTag = me.mTraceTag;
        if(traceTag !=0 && Trace.isTagEnabled(traceTag)){
           Trace.traceBegin(traceTag,msg.target.getTraceName(msg));
        }
        try{
            msg.target.dispatchMessage(msg);// 分发消息给发送消息的handler处理
        }finally{
            if(traceTag != 0){
                Trace.traceEnd(traceTag);
            }
        }
         if(logging != null){
            logging.println("<<<<< Finished to "+msg.target+" "+msg.callback);
        }
       // Make sure that during the course of dispatching the
        // identity of the thread wasn't corrupted.
        final long newIdent = Binder.clearCallingIdentity();
        if(ident != newIdent){
            Log.wtf(TAG,"Thread identity changed from 0x"
            +Long.toHexString(ident)+" to 0x"
             +Long.toHexString(newIdent)+" while dispatching to "
            +msg.target.getClass().getName()+" "
            +msg.callback+" what="+msg.what);
        }
        msg.recycleUnchecked();
    }
}
上一篇下一篇

猜你喜欢

热点阅读