先来看以下View.requestLayout源码
/**
* Call this when something has changed which has invalidated the
* layout of this view. This will schedule a layout pass of the view
* tree.
*/
public void requestLayout() {
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;
if (mParent != null && !mParent.isLayoutRequested()) {
// 先上传递,最总到达顶层View即RootViewImpl
mParent.requestLayout();
}
}查看下ViewRootImpl.requestLayout源码
public void requestLayout() {
// 检测是否在UI线程
checkThread();
mLayoutRequested = true;
// 重点
scheduleTraversals();
} public void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
//noinspection ConstantConditions
if (ViewDebug.DEBUG_LATENCY && mLastTraversalFinishedTimeNanos != 0) {
final long now = System.nanoTime();
Log.d(TAG, "Latency: Scheduled traversal, it has been "
+ ((now - mLastTraversalFinishedTimeNanos) * 0.000001f)
+ "ms since the last traversal finished.");
}
// 发出一个遍历的Handler信息
sendEmptyMessage(DO_TRAVERSAL);
}
}RootViewImpl.handleMessage方法源码:
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
case DO_TRAVERSAL:
if (mProfile) {
Debug.startMethodTracing("ViewAncestor");
}
final long traversalStartTime;
if (ViewDebug.DEBUG_LATENCY) {
traversalStartTime = System.nanoTime();
mLastDrawDurationNanos = 0;
}
// 接收到消息之后,开始执行遍历,具体measure,layout,draw操作
performTraversals();
if (ViewDebug.DEBUG_LATENCY) {
long now = System.nanoTime();
Log.d(TAG, "Latency: Spent "
+ ((now - traversalStartTime) * 0.000001f)
+ "ms in performTraversals(), with "
+ (mLastDrawDurationNanos * 0.000001f)
+ "ms of that time in draw()");
mLastTraversalFinishedTimeNanos = now;
}
if (mProfile) {
Debug.stopMethodTracing();
mProfile = false;
}
break;
......
}
}
本文通过对View.requestLayout和ViewRootImpl的相关源码分析,揭示了Android中布局更新的内部工作原理,探讨了requestLayout方法如何触发视图的重新测量和绘制流程。
2万+

被折叠的 条评论
为什么被折叠?



