Looper与Handler是如何通过Message发生关系的


经常看到Android的消息用法大概为:
Looper.prepare()
Looper.myLooper();
xxxHandler = new Handler() {     
handleMessage(Message msg){...} 
};  
Looper.loop();


刚开始搞不清楚状况, 根据名字完全看不出有什么关系的两个类,到底如何进行消息传递呢? 只是知道就这么用就没问题的, 应该不少人跟我一样吧.


如然有兴趣来解刨一下吧.
Looper.prepare();  里面有一句  sThreadLocal.set(new Looper()); 
这里就new 了一个Looper了, 然后放到ThreadLocal里面, 这是个线程数据共享的一个类. 
    private Looper() {
        mQueue = new MessageQueue();   
        mRun = true;
        mThread = Thread.currentThread();
    }
在这里面就传递了当前的工作线程的信息,并且new了一个message queue,就是消息队列嘛, 用来接收消息的容器.


    public static Looper myLooper() {
        return sThreadLocal.get();
    } 
这个函数就返回了上面创建的那个new Looper();


public Handler() { 
...
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
...
}
在这里就把当前线程的Looper赋给Handler了, 这就发生关系了.


可能有同学还会有疑问, 上面是两个类的不同的语句Looper.myLooper();怎么得到的是同一个呢?
那就分析一下吧;
在Looper类里面有个全局的静态容器
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
再进入ThreadLocal类里面看
    public void set(T value) {
        Thread currentThread = Thread.currentThread();
        Values values = values(currentThread);
        if (values == null) {
            values = initializeValues(currentThread);
        }
        values.put(this, value);
    }
在这里就把当前的线程的相关信息设进去了.
看看get()函数;
    public T get() {
        // Optimized for the fast path.
        Thread currentThread = Thread.currentThread(); 
        Values values = values(currentThread);
        if (values != null) {
            Object[] table = values.table; 
            int index = hash & values.mask;
            if (this.reference == table[index]) {
                return (T) table[index + 1];                                                                                                   
            }
        } else {
            values = initializeValues(currentThread);                                                                                          
        }


        return (T) values.getAfterMiss(this);                                                                                                  
    } 
再这里就返回了当前线程的相关信息. 


因为ThreadLocal是个模板容器, 声明为ThreadLocal<T>
在Looper中声明为ThreadLocal<Looper> , 所以 T == Looper .


简单的翻译一下上面的get()和set()吧;
public void set(Looper value) {
values.put(this, value);
}


public void Looper get() {
return values.get(this);
}


这样就很清晰了, 关系就是这么发生的. 回头梳理一下吧. 
Looper.prepare()   
Looper.myLooper();
xxxHandler = new Handler(){  handleMessage(Message msg){...} };  
Looper.loop();
等价于
Looper.prepare() {  sThreadLocal.set(currentThread, new  Looper(); }
Looper.myLooper() { sThreadLocal.get(currentThread) }
new Handle(){  
...
mLooper = sThreadLocal.get(currentThread); 
mQueue = mLooper.mQueue;
...}


关系发生了,这时候就可以通过Message进行通信了, 这就不多说了.


你可能感兴趣的:(Looper与Handler是如何通过Message发生关系的)