-
清除测量记录;
-
增加 PFLAG_FORCE_LAYOUT 给 mPrivateFlags;
-
如果 mParent 没有调用过 requestLayout(),则调用之。换句话说,如果调用过,则不会继续调用;
重点看下 mParent.isLayoutRequested() 方法,它在 View.java 中有具体实现。
//View.java
public boolean isLayoutRequested() {
return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
}
如果
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
mPrivateFlags 增加了 PFLAG_FORCE_LAYOUT 标志位,则认为 View 已经请求过布局。
由前文可知,在 requestLayout() 的第二步,会增加该标志位。熟悉位操作的朋友就会知道,有增加操作就会有对应的清除操作。
经过一番搜索,找到:
//View.java
public void layout(int l, int t, int r, int b) {
// … 省略代码
//在View调用完layout方法,会将PFLAG_FORCE_LAYOUT标志位清除掉
mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
// … 省略代码
}
在 View 调用完 layout() 方法,会将 PFLAG_FORCE_LAYOUT 标志位清除掉。当 View 下次再调用 requestLayout() 方法时,依旧能往上层层调用。但是如果当 layout() 方法没有执行时,下次再调用 requestLayout() 方法时,就不会往上层层调用了。
回答文章中的第一个问题:
Q:锁屏后,调用 View.requestLayout(),会往上层层调用 requestLayout() 吗?
A:锁屏后,除了第一次调用会往上层层调用,其它的都不会。
为什么,只有第一次调用会呢?
那必定是因为之后的 layout() 方法没有得到执行,导致 PFLAG_FORCE_LAYOUT 无法被清除。
欲探究竟,接着往下看。
如果你知道 requestLayout() 调用是一个层级调用,那么恭喜你,你已经处于认知的第一层了。送你一张二层入场券。
==================================================================================
我们来看看第一层讲到的 ViewRootImpl.requestLayout()。
//ViewRootImpl.java
@Override
public void requestLayout() {
if (!mHan