activity view draw

引言

activity 生命周期大家都比较清楚,onAttach->onCreate->onStart>onResume->onStop->onDestroy。 但是 activity 的 view 绘制到底发生在什么时候,它的创建、绘制、前台可交互等等的时期。

详解

我们在 activity onCreate 里面会设置 setContentView。实际上是创建了一个 view,它的目标是创建 DecorView ,进行初始化和布局的加载。

1
2
3
4
5
6
mWindow = new PhoneWindow(this, window, activityConfigCallback);

public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}

但在源码里面 ActivityThread 里可以看到是在 onResume 之后,把 DecorView 添加到 WindowManager,从这时候开始该 activity 开始绘制到屏幕上。由 WindowManager 移交给 ViewRootImpl 渲染绘制。绘制完成后即开始交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
// We didn't actually resume the activity, so skipping any follow-up actions.
return;
}
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
...
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
// The activity will get a callback for this {@link LayoutParams} change
// earlier. However, at that time the decor will not be set (this is set
// in this method), so no action will be taken. This call ensures the
// callback occurs with the decor set.
a.onWindowAttributesChanged(l);
}
}

// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
...
}

总结

现在我们对 activity view 展示、初始化、绘制时机等等有了一个基础的了解。这有什么用呢?
比如如果我们想知道 activity 的绘制完成时间,那么很明显,除了重写 onWindowFocusChanged 方法外,最准确的是 DecorView 的绘制完成,可以监听其 onDraw 完成后的一次 vsync。