全面分析Handler消息机制

作者: 捉影T_T900 | 来源:发表于2017-09-15 00:16 被阅读35次

    转载一篇Handler机制文章以加深理解
    http://blog.csdn.net/sinat_23092639/article/details/52334398

    核心内容提要:
    1、Handler就是一个和创建当前Handler对象的线程和线程的消息队列绑定的组件。

    2、Looper是针对某个线程开启消息循环,线程是默认没有消息循环的,要调用prepare来为当前线程设置一个Looper,调用loop开启消息循环直到循环结束为止。

    3、核心代码分析

    public Handler(Callback callback, boolean async) {   
           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;  
       }  
    

    (1)Handler不能没有Looper,否则报异常。
    (2)Looper对象持有MessageQueue引用。

    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));  
        } 
    

    (1)一个线程只能拥有设置一个Looper对象
    (2)将Looper对象设置到ThreadLocal内

    public static @Nullable Looper myLooper() {  
            return sThreadLocal.get();  
        }  
    

    (1)获取ThreadLocal内的Looper对象

    4、消息发送机制

    sendMessage
    sendMessageDelay
    sendMessageAtTime
    enqueueMessage 【最终调用】

    5、获取消息
    loop循环提取MessageQueue队列内的消息

    6、总结:
    一个线程对应一个Handler,因为Handler的构造函数内获取的是绑定了该线程的Looper;

    一个线程只能一个Looper对象,从而只有一个MessageQueue(在Looper的构造方法初始化);

    所有的线程共享同一个ThreadLocal对象,不同线程向ThreadLocal对象设置的Looper不同;

    这里的关键还是ThreadLocal类,它可以在Handler对象需要与Looper对像关联的时候提供当前;

    线程的关联的Looper,并从该Looper得到当前线程的消息队列引用,从而使得Handler对象在发送消息的时候可以发送到创建自己的线程的消息队列。而
    此时该线程的Looper消息循环执行Message的时候已经在创建Handler的线程中;

    使用静态的Handler对象避免出现内存泄漏。

    相关文章

      网友评论

        本文标题:全面分析Handler消息机制

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