全面分析Handler消息机制

转载一篇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消息机制)