Handler,Loop,Message,MessageQueue,ThreadLocal关系详解

一直对handler机制一知半解,花了两天时间对handler从信息发送到接收,网上翻阅了一些资料结合源码重新滤了一遍,做下笔记,便于以后查阅,记忆是靠不住的。

handler机制的整个过程就是handler发送信息给looper,looper在适当的时候通过handler的dispatchMessage方法回调给handler的过程,

Handler:

android ui的改变是只能在主线程,如果子线程也能改变就会造成线程不安全。子线程要改变ui就需要线程间通信。handler是子线程刷新ui的唯一方式(runOnUiThread和view.post本质上都是handler)。Handler的构造方法需要传入looper,如果没有传默认使用当前线程的looper。Handler通过looper,获取到MessageQueue队列,在将message塞进MessageQueue里面。

Handler有5个post runnable的方法和7个send message的方法,post runnable会通过getPostMessage的方法转成send message的方法,会把runnalbe赋值给Message的callback变量(dispatchMessage会用到),最终都是调用messageQueue的enqueueMessage,在调用该方法之前,会把当前的handler赋值给message的target变量,这个很重要,这个是looper通过message找到对应handler的关键。

handler发送的部份讲完了,接下来就等着dispatchmessage被回调。dispatchMessage做的处理也很简单,判断message的callback是否为空,就是判断是否是post runnable的调用,如果不为空直接处理,message.callback.run()也就是调用runnable的run方法。如果为空,就调用handler子类实现的handleMessage方法。


Looper

一个looper对应一个线程,一个线程最多只能有一个looper。主线程默认是有创建looper,并进行loop循环的。子线程默认是没有loop的,需要通过Looper.prepare创建looper,并通过Looper.loop进行消息队列的循环处理。

所以我们来看看Looper的prepare和loop两个关键的方法做了什么,prepare方法new looper并将创建的looper set到ThreadLocal里面(这个ThreadLocal是什么,为什么这么做,我们下面在说)。这样prepare工作就完成了,prepare是必须在loop方法之前调用。

在来看看loop方法,通过ThreadLocal的get方法获取looper,prepare怎么存,我们现在就怎么取,取到looper后就取到MessageQueue,然后就死循环处理队列里面的message,message.target.dispatchMessage,通过message的target变量回调handler的dispatchMessage。这样hander到looper的循环就讲完了。


Message

数据类,用于Hander和looper的交互,数据传递


MessageQueue

message的数据队列


ThreadLocal

ThreadLocal是数据存储类,存储于线程相关的数据,但它并没有直接和Thread打交道,而是通过它的内部类ThreadLocal.value与thread类沟通,每个thread都有一个ThreadLocal.value的成员变量,value是一个存储键值对的容器,ThreadLocal把自己当成键值,looper当成value,存储到ThreadLocal.value,这样Looper就与thread相关联。 每个Looper都有一个ThreadLocal,键值唯一,Looper就和thread一一对应。


ps: 怎么保证在一个线程(线程A)定义的handler,在其他线程(线程B)中通过这个handler调用的send message,怎么能保证handerl的dispatchMessage就能在线程A中执行呢。我是这么理解的,Looper是存储在Thread里面的,就是looper是属于线程A的,MessageQueue是属于looper的,message是属于messgequeue,所以message是属于线程A的,那message调用的dispatchmessge也应该是在线程A中执行的,不知道这样理解是否有误。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值