

这是整个绘制流程的起点,位于frameworks/base/core/java/android/app/ActivityThread.java:
public void handleResumeActivity(IBinder token, boolean finalStateRequest,
boolean isForward, String reason) {
// 1. 执行Activity的onResume生命周期
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r != null) {
final Activity a = r.activity;
//...
if (r.window == null && !a.mFinished && willBeVisible) {
// 2. 获取DecorView
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
// 3. 获取WindowManager
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
// 4. 关键调用:添加DecorView到窗口系统
wm.addView(decor, l);
}
}
}此方法位于frameworks/base/core/java/android/view/WindowManagerGlobal.java:
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
synchronized (mLock) {
// 1. 创建ViewRootImpl实例
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
// 2. 保存视图引用
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
// 3. 核心调用:关联视图与ViewRootImpl
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// 异常处理
}
}
}位于frameworks/base/core/java/android/view/ViewRootImpl.java:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view; // 保存DecorView引用
// 1. 请求首次布局
requestLayout();
// 2. 通过Binder与WMS通信
try {
mWindowSession.addToDisplayAsUser(...);
} catch (RemoteException e) {
// 异常处理
}
// 3. 设置输入事件接收器
mInputEventReceiver = new WindowInputEventReceiver(...);
}
}
}@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
// 1. 检查是否在主线程
checkThread();
// 2. 标记布局请求
mLayoutRequested = true;
// 3. 调度遍历任务
scheduleTraversals();
}
}void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
// 1. 插入同步屏障(确保UI绘制优先)
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 2. 通过Choreographer注册VSync回调
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL,
mTraversalRunnable, // 关键回调
null
);
// 3. 通知渲染管道
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
}
}当VSync信号到达时,触发回调链:
// mTraversalRunnable的实现
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
// 1. 移除同步屏障
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
// 2. 执行核心遍历
performTraversals();
}
}这是整个绘制流程的核心(精简版):
private void performTraversals() {
final View host = mView; // 即DecorView
// 第一阶段:预测量
if (mFirst) {
// 1. 与WMS通信获取窗口尺寸
relayoutResult = relayoutWindow(params, ...);
// 2. 收集View树所需系统配置
collectViewAttributes();
}
// 第二阶段:测量(Measure)
if (layoutRequested) {
// 1. 创建MeasureSpec
int childWidthMeasureSpec = getRootMeasureSpec(...);
int childHeightMeasureSpec = getRootMeasureSpec(...);
// 2. 执行DecorView的测量
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
}
// 第三阶段:布局(Layout)
if (didLayout) {
// 1. 执行DecorView的布局
performLayout(lp, mWidth, mHeight);
// 2. 处理键盘导航变化
if ((host.mPrivateFlags & PFLAG_FOCUSED) != 0) {
host.restoreDefaultFocus();
}
}
// 第四阶段:绘制(Draw)
if (!cancelDraw && !newSurface) {
// 1. 判断是否需要完整重绘
boolean fullRedrawNeeded = mFullRedrawNeeded;
// 2. 执行绘制
performDraw();
}
// 第五阶段:清理
if (mFirst) {
mFirst = false; // 标记首次遍历完成
}
}private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
try {
// 调用DecorView的measure()方法
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}核心机制:
MeasureSpec向子View传递约束条件onMeasure()计算自身尺寸private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
// 设置宿主窗口尺寸
host.setFrame(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
// 执行DecorView的layout()
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
}核心机制:
layout()onLayout()确定子View位置setFrame()设置每个View的最终位置private void performDraw() {
try {
boolean canUseAsync = draw(fullRedrawNeeded);
//...
} finally {
mIsDrawing = false;
}
}
private boolean draw(boolean fullRedrawNeeded) {
if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
scalingRequired, dirty, surfaceInsets)) {
return false;
}
return true;
}
private boolean drawSoftware(Surface surface, AttachInfo attachInfo,
int xoff, int yoff, boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
// 1. 锁定Canvas
Canvas canvas = surface.lockCanvas(dirty);
try {
// 2. 执行DecorView的draw()
mView.draw(canvas);
} finally {
// 3. 解锁并提交渲染
surface.unlockCanvasAndPost(canvas);
}
return true;
}核心机制:
draw()Choreographer实现绘制与显示刷新率同步
Looper.getQueue().postSyncBarrier()removeSyncBarrier()移除mDirty区域标记需要重绘的部分<merge>标签或ConstraintLayout优化// 错误示例:在onResume中直接获取宽高
protected void onResume() {
super.onResume();
int width = myView.getWidth(); // 返回0
}
// 正确做法
protected void onResume() {
super.onResume();
myView.post(() -> {
int width = myView.getWidth(); // 正确值
});
}ViewStub延迟加载复杂布局canvas.clipRect()限制绘制区域setLayerType(LAYER_TYPE_HARDWARE)onCreate()中预加载数据Activity的View首次绘制是一个精密的系统级协作过程:
handleResumeActivity()启动流程WindowManager.addView()关联视图与ViewRootImplChoreographer协调硬件信号与软件绘制理解此流程对开发高性能UI至关重要,尤其在优化启动速度和滚动流畅性时,能帮助开发者准确定位性能瓶颈。建议结合Systrace工具实际验证绘制流程各阶段耗时,实现精准优化。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。