Android线程切换之谜

作者: 一只小松 | 来源:发表于2017-08-04 19:30 被阅读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();
        }
    }
    

    相关文章

      网友评论

        本文标题:Android线程切换之谜

        本文链接:https://www.haomeiwen.com/subject/ateblxtx.html