Handler的绑定过程

来源:互联网 发布:象棋软件哪个厉害 编辑:程序博客网 时间:2024/06/06 18:13


 

研究了一下Handler的源码,总结其绑定线程及创建消息队列的过程如下:

Looper绑定线程的过程:(以下截图都是源码截图)以下图为例:

 

 

Looper.prepare()方法中,创建Looper对象和消息队列,绑定线程,并创建Values集合,以便handler获取到looper对象

 

sThreadLocal.set(new Looper(quitAllowed))ThreadLocal类(可用当前线程创建一个线程副本的一个类)的方法,其中的new Looper(quitAllowed)不难看出,Looper绑定消息队列的过程(很简单,mQueueLooper的属性),Looper绑定线程的过程(也很简单,mThreadLooper的属性)。

 

新建Looper对象的时候,就创建了mQueue ,方便此后的sThreadLocal.set()的执行;

 

 

其中Values是一个Map集合,是ThreadLocal的一个内部类,即把当前ThreadLocal对象作为key,value(Looper对象)作为值,添加到Values集合中,

Looper绑定了线程和消息队列,那么久还差Handler没绑定了。

Looper.prepare()方法后面紧接着创建Handler对象,利用空构造方法,以内部类的形式创建handler对象,

 

在空的构造方法里,有调用了有两个参数的构造方法,即下图的方法

 

其中又调用了mLooper = Looper.myLooper();方法来获取looper对象,

 

myLooper()方法中又调用了ThreadLocal get()方法,看return就行,

有调用values.getAfterMiss(this),如下图

 

从Values集合中获取了Looper对象,这样就实现了线程的绑定。

 

 

下面是消息读取原理

由下图不难看出,Message msg = queue.next();获取消息的语句被放在for(;;)死循环里,这就意味着它不停地获取消息,而MessageQueuenext(),如果读到null岂不是会退出死循环?

 

必须是!但请再看看这个next()方法,不难看出next()也是一个for(;;)死循环,

 

而只有读到的msg不为空时才跳出循环,如下图

 

还有一种情况,当进程(不是线程)退出时,next()也会退出死循环

 


0 0
原创粉丝点击