handler之java源码分析
2021-06-10 11:34:11 0 举报
对handler详细分析
作者其他创作
大纲/内容
新Entry
创建Handler对象
msg=0
场景
IdleHandler
1、根据key.threadLocalHashCode & (table.length - 1)找到数组中存放的位置,如果占用放入后面一个位置2、resize是2倍扩容
假如:当前是主线程
Entry
不唤醒
回调handler中方法handleMessage
UI更新
dispatchMessage见下图
判断两种情况,插入队列中间
Looper对象
默认返回false
handler发送的时候从消息池中获取
直接唤醒
msg异步消息when=1点
获取msg返回
IdleHandler执行
msg屏障消息
消息池为空
执行queueIdle
needWake=true
阻塞
取出
进入休眠阻塞
msg
handler的post方法放入的msg
msg异步消息when=3点
移除屏障消息removeSyncBarrier
msg2
Looper循环
ThreadLocal存储
获取到异步msg返回
事件分发
退出方法
Looper.loop
needWake=false
mCallback==null
msgwhen=2点,插入中间
obtain()头msg
recycle将msg头
when=0调用sendMessageAtFrontOfQueue
非屏障消息
当前when=1点queue.next();阻塞
p==null
handler的dispatchMessage
mCallback != null
msg.arg1=token(区分屏障)
needWake = mBlocked && p.target == null && msg.isAsynchronous();
sPool头指针
threadlocalmap数组
queue放入普通消息enqueueMessage
移除mIdleHandlers
msgwhen=3点
屏障消息msg.target == null
p == null || when == 0 || when < p.when
sPool消息池
msgtarget:handler
msg3
根据when插入到对应位置
当前when=2点queue.next();取出消息
特点
msg.target.dispatchMessage(msg);
1、p == null,队列为空2、when == 0,立马执行的消息3、当前消息时间<当前链头的时间
系统处理比较紧急的事
queue.next
回调msg.callback
放入屏障消息postSyncBarrier
MessageQueue
mIdleHandlers放入mPendingIdleHandlers数组中
1、通过looper循环,拿出头部的第一个消息2、通过msg中target找到之前是哪个handler调用的,执行handlerMessage3、注意这里回调的方法
当nextPollTimeoutMillis = -1时,表示消息队列中无消息,会一直等待下去
修改返回true
ThreadLocalMap中维护的数组长度是16
空
执行完成后回收msg
计算需要休眠的时间
拿出头部msg
mIdleHandlers缓存在集合中
空或非空
sendEmptyMessage
4点
成员变量mCallback
唤醒p == null || when < p.when情况一:只有一个屏障消息情况二:队列中的异步消息晚 //将消息按时间顺序插入到MessageQueue。一般地,不需要唤醒事件队列,除非消息队头存在barrier,并且同时Message是队列中最早的异步消息。
msg 3点
屏障消息
msg 2点
线程和threadlocalma=1:1
正常插入的同步消息
msg 4点
key是弱引用WeakReference<ThreadLocal<?>>
只会挡住同步消息,不挡异步消息
MessageQueue
handleMessage
ThreadLocalMap
回调mCallback.handleMessage(msg)
enqueueMessage见右图
调用,阻塞操作
Handler处理消息的整个流程图
阻塞操作1、当等待nextPollTimeoutMillis时长2、消息队列被加入的新消息唤醒
插入
非阻塞
循环遍历执行
不移除还会执行
第一次循环
3点
当前时间小于头部的消息
when=2点,插入头
异步或者同步msg
msgwhen=1点
阻塞同步消息
唤醒
msg1
0 条评论
回复 删除
下一页