Handler机制源码分析
Handler
handler持有成员变量
handler构造
构造详细调用
通过Loop.myLooper更新Looper对象
发送消息相关
发送消息最终指向函数
最终都是调用 queue.enqueueMessage消息发送
可以看出来 callback只是在 handler.dispatchMessage时进行消息回调
handler类只能看到executeOrSendMessage 对消息进行了分发,看不到调用方,应该是外部调用handler.executeOrSendMessage
Looper分析
主要维持一个 sThreadLocal,sMainLooper,mQueue,mThread引用
Looper私有化了构造,只能通过prepare 或者myLooper调用获得
myLooper是从sThreadLocal中获取,prepare是new出来,并且new之前还进行非空异常抛出,明显是阻止多次创建,new出来后还使用sThreadLocal进行了保存
回看Handler构造,无参构造都调用myLooper从sThreadLocal进行了获取Looper对象,取不到就抛异常,联想我们主线程new Handler() 说明主线程 sThreadLocal 必定可以获取到 Looper
又一个对外的静态方法,还得保证从sThread中拿不到 Looper才进行 myLooper调用获得Looper对象,说明该方法 prepareMainLooper必须非主线程调用
Looper.loop()方法,比较长,这里主要内容,通过myLooper() 从sThreadLocal获取 Looper对象,queue.next获取消息节点Message,msg.target.dispatchMesage 进行消息转发,这里的target就是handler,后续源码会看到
MessageQueue
持有变量比较重要的有Message
next主要是修改Message链表指针,移出之前的message;enqueueMessage是将新传入的Message加到链表并偏移指针
Message
Message 就是构造,可以发现 Message target是调用的handler,也就是说Message携带了Handler,方便被移出MessageQueue值执行调用,将本身传给自己携带的Handler
ThreadLocal
可以发现就是个线程实例维护的hash存储工具
疑问1:主线程Looper哪里来
可以发现 Activity main入口进行了 Looper准备,准备会将Looper绑定到主线程的ThreadLocal 。
总结
主线程在main入口函数自动准备Looper对象
Looper绑定MessageQueue,负责存储和转发消息到MessageQueue
MessageQueue操作Message链表,存储获取消息
Message携带Handler,Handler只是回调
Message消费就是移出链表,并传给自己携带的Handler
Looper绑定线程,一个线程只能一个
子线程new Handler需要传入Looper ,因为子线程的sThreadLocal中没有预先初始化Looper