Handler分析

Handler分析


1.Handler分析

Handler涉及了MessageQueue,Looper几个类,可以用一句话概括。Looper不断获取MessageQueue中的一个Message,然后由Handler处理。下面分析代码

1.1Handler

    Handler主要有两个方面的作用:
        1.处理Message
        2.把Message压入MessageQueue
    public class Handler {

        /**主要几个成员变量*/
        final Looper mLooper;
        final MessageQueue mQueue;
        final Callback mCallback;

        public Handler(Callback callback, boolean async) {
            if (FIND_POTENTIAL_LEAKS) {
                final Class<? extends Handler> klass = getClass();
                if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                    Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                        klass.getCanonicalName());
            }
        }
            //得到当前线程的Looper,就是在Looper.prepare()中存储在当前线程的
            mLooper = Looper.myLooper();
            if (mLooper == null) {
                throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
            mQueue = mLooper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
    }

        /**压入Message的方法,主要分为post和send系列,区别是post的参数是一个Runable,send的参数是Message*/
        public final boolean post(Runnable r){
            return  sendMessageDelayed(getPostMessage(r), 0);
        }
        public final boolean postAtTime(Runnable r, long uptimeMillis){
            return sendMessageAtTime(getPostMessage(r), uptimeMillis);
        }
        //可以发现post也调用了send系列,其中使用了getPostMessage(r)把Runable封装成Message
         public final boolean sendMessage(Message msg){
            return sendMessageDelayed(msg, 0);
        }
        public final boolean sendMessageDelayed(Message msg, long delayMillis){
            if (delayMillis < 0) {
                delayMillis = 0;
            }
            return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
        }
        //最终都调用这个方法,把Message通过压入MessageQueue队列
        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
            MessageQueue queue = mQueue;
            if (queue == null) {
                RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
                Log.w("Looper", e.getMessage(), e);
                return false;
            }
            return enqueueMessage(queue, msg, uptimeMillis);
        }
        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            msg.target = this; //--------->  :)   很关键,每个Message都携带了一个Handler本身,在一个线程新建Handler对象在其他线程发出message
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            return queue.enqueueMessage(msg, uptimeMillis);
        }
    }

1.2Looper分析

分析之前先说明在一个非主线程中如何使用Handler,根据这些使用来分析Looper的代码

    class LeoThread extends Thread{
        public Handler mHandler;
        public void run(){
            Looper.prepare();
            mHandler = new Handler(){
                public void handleMessage(Message msg){
                    //自己写一些处理逻辑
                }
            }
            Looper.loop();
        }
    }

下面分析Looper代码

    public final class Looper{

         static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();   //是一个特殊的全局变量,全局性仅仅在本线程,这个变量可以把Looper存储起来,其他地方取出来,使本线程唯一
        private static Looper sMainLooper;  // guarded by Looper.class

        final MessageQueue mQueue;
        final Thread mThread;

        //1.使用Looper.prepare()方法初始化一个Looper存储起来
        public static void prepare() {
            prepare(true);
        }
        private static void prepare(boolean quitAllowed) {
            if (sThreadLocal.get() != null) {
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper(quitAllowed));
        }

        private Looper(boolean quitAllowed) {
            mQueue = new MessageQueue(quitAllowed);
            mThread = Thread.currentThread();
        }
        //2.new一个新的Handler,重写handleMessage方法处理得到在Message,在Handler的初始化方法中会得到得到上面的Looper对象,handler中的Messagequeue就是looper中的
        //3.Looper.loop()
        public static void loop() {
            //得到Looper.prepare()前面存储在线程中在Looper
            final Looper me = myLooper();
            if (me == null) {
                throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
            }
            final MessageQueue queue = me.mQueue; //消息队列

            // 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();

            //死循环从队列获取message进行处理
            for (;;) {
                Message msg = queue.next(); // might block
                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 long traceTag = me.mTraceTag;
                if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                    Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
                }
                try {
                    //Handler是携带在Message中的,上面分析过了
                    msg.target.dispatchMessage(msg);
                } 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();
            }
        }
    }


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值