先来看以下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;
......
}
}