标签:mActions mRunQueue Handler HandlerAction action post null android
}
// 仔细阅读下面这段注释!!!
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
从上面的源码,我们大概可以看出mAttachInfo
字段在这里比较关键,当其有值时,其实和普通的Handler.post
就没区别了,但
有时它是没值的,比如我们上面示例代码里的onCreate阶段,那么这时执行到了getRunQueue().post(action);
这行代码,从这段注释也大概可以看出来真正的执行会被延迟(这里的Postpone
注释);我们接着往下看看getRunQueue相关的代码,如下:
/** 其实这段注释已经说的很清楚明了了!!!
- Queue of pending runnables. Used to postpone calls to post() until this
- view is attached and has a handler.
*/
private HandlerActionQueue mRunQueue;
private HandlerActionQueue getRunQueue() {
if (mRunQueue == null) {
mRunQueue = new HandlerActionQueue();
}
return mRunQueue;
}
从上面我们可以看出,mRunQueue就是View用来处理它还没attach到window(还没对应的handler)时,客户代码发起的post调用的,起了一个临时缓存
的作用。不然总不能丢弃吧,这样开发体验就太差了!!!
紧接着,我们继续看下HandlerActionQueue
类型的定义,代码如下:
public class HandlerActionQueue {
private HandlerAction[] mActions;
private int mCount;
public void post(Runnable action) {
postDelayed(action, 0);
}
public void postDelayed(Runnable action, long delayMillis) {
final HandlerAction handlerAction = new HandlerAction(action, delayMillis);
synchronized (this) {
if (mActions == null) {
mActions = new HandlerAction[4];
}
mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);
mCount++;
}
}
public void executeActions(Handler handler) {
synchronized (this) {
final HandlerAction[] actions = mActions;
for (int i = 0, count = mCount; i < count; i++) {
final HandlerAction handlerAction = actions[i];
handler.postDelayed(handlerAction.action, handlerAction.delay);
}
mActions = null;
mCount = 0;
}
}
private static class HandlerAction {
final Runnable action;
final long delay;
public HandlerAction(Runnable action, long delay) {
this.action = action;
this.delay = delay;
}
public boolean matches(Runnable otherAction) {
return otherAction == null && action == null
|| action != null && action.equals(otherAction);
}
}
}
注意:这里的源码部分,我们只摘录了部分关键代码,其余不太相关的直接略去了。
从这里可以看出,我们前面的View.post调用里的Runnable最终会被存储在这里的mActions
数组里,这里最关键的一点就是其executeActions
方法,因为这个方法里我们之前post的Runnable才真正通过handler.postDelayed
方式使其进入handler对应的消息队列里等待执行;
到此为止,我们还差知道View里的mAttachInfo
字段何时被赋值以及这里的executeActions
方法是什么时候被触发的,答案就是在View的dispatchAttachedToWindow
方法,其关键源码如下:
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
…
// Transfer all pending runnables.
if (mRunQueue != null) {
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
performCollectViewAttributes(mAttachInfo, visibility);
onAttachedToWindow();
…
Queue = null;
}
performCollectViewAttributes(mAttachInfo, visibility);
onAttachedToWindow();
…
标签:mActions,mRunQueue,Handler,HandlerAction,action,post,null,android 来源: https://blog.csdn.net/wa32saa/article/details/122759546
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。