几个关键类
WindowManager
-
WindowManager 是以服务的形式;
1
context.getSystemService(Context.WINDOW_SERVICE)
-
WindowManager 的实际能力由 WindowManagerGlobal 提供,它是一个单例。
-
WindowManagerGlobal 内部维持一个 ViewRootImpl 列表
1 2 3
WindowManagerImpl ➜ WindowManagerGlobal -> singleInstance ➜ ArrayList<ViewRootImpl> mRoots
Choreographer
-
请求与接收 vsync 信号
-
核心是它的内部类
FrameDisplayEventReceiver
,核心能力是:-
通过 native 接受系统发送的 vsync 信号;
-
请求下一个 vsync 信号;
-
-
核心方法如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 请求下一帧 vsync 事件 public void scheduleVsync() { nativeScheduleVsync(mReceiverPtr); } private static native void nativeScheduleVsync(long receiverPtr); // vsync 回调,Called from native code. private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,VsyncEventData vsyncEventData) { onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); } public void onVsync(long timestampNanos, long physicalDisplayId, int frame,VsyncEventData vsyncEventData) { doFrame(mTimestampNanos, mFrame, mLastVsyncEventData); }
-
-
消息”蓄水池“
持有
mCallbackQueues
队列,将Input
,Animation
,Traversal
,Commit
事件保存起来,等待下次 vsync 信号到来后,再一次性消费;-
mCallbackQueues 队列初始化
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
public static final int CALLBACK_INPUT = 0; public static final int CALLBACK_ANIMATION = 1; public static final int CALLBACK_INSETS_ANIMATION = 2; /** * Handles layout and draw. * Runs after all other asynchronous messages have been handled. */ public static final int CALLBACK_TRAVERSAL = 3; /** * Handles post-draw operations for the frame. * Runs after traversal completes. */ public static final int CALLBACK_COMMIT = 4; private static final int CALLBACK_LAST = CALLBACK_COMMIT; private final CallbackQueue[] mCallbackQueues; // 构造函数: private Choreographer(Looper looper, int vsyncSource) { // ... mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1]; for (int i = 0; i <= CALLBACK_LAST; i++) { mCallbackQueues[i] = new CallbackQueue(); } }
-
接收消息
1 2 3 4 5 6 7
private void postCallbackDelayedInternal(int callbackType, Object action, Object token, long delayMillis) { synchronized (mLock) { final long dueTime = SystemClock.uptimeMillis() + delayMillis; // 每个 callbackType 独立以链表存储各自的消息 mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token); } }
-
消费消息
1 2 3 4 5 6 7 8
void doFrame(long frameTimeNanos, int frame, DisplayEventReceiver.VsxxData vd) { // ... doCallbacks(Choreographer.CALLBACK_INPUT, frameData, frameIntervalNanos); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameData, frameIntervalNanos); doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameData, frameIntervalNanos); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameData, frameIntervalNanos); doCallbacks(Choreographer.CALLBACK_COMMIT, frameData, frameIntervalNanos); }
-
ViewRootImpl
- ViewRootImpl 实现了 View 和 WindowManager 之间所需要的协议;每个应用程序窗口都有一个对应的 ViewRootImpl 实例,比如 Activity。
- ViewRootImpl 是应用程序和 Android framework 沟通的桥梁,包括持有 Choreographer 以交互视图信息;还有:
- WindowInputEventReceiver:接收屏幕点击触摸事件;
- InputStage:接收并处理输入法事件;
- ViewRootImpl 中的
performTraversals
方法管理了 View 的 measure,layout,draw 三个核心步骤;
绘制初始化流程
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
ActivityThread.handleLaunchActivity
➜ ActivityThread.performLaunchActivity
➜ Activity.attach // 初始化 window,并绑定 WindowManager
➜ mWindow = new PhoneWindow
➜ mWindow.setCallback(this);
➜ mWindow.setWindowManager(getSystemService(Context.WINDOW_SERVICE))
➜ Activity.onCreate // 在 onCreate 中 setContentView 流程
➜ Activity.setContentView
➜ mWindow.setContentView
➜ PhoneWindow.installDecor
➜ new DecorView(PhoneWindow.this)
ActivityThread.handleResumeActivity
➜ ActivityThread.performResumeActivity
➜ Activity.onResume
➜ activity.mWindow.getWindowManager().addView(activity.mWindow.getDecorView(),xxx)
➜ WindowManagerGlobal.addView
➜ new ViewRootImpl
➜ new View.AttachInfo(ViewRootImpl.this)
➜ viewRootImpl.setView(decorView)
➜ new Choreographer
➜ new FrameDisplayEventReceiver
➜ requestLayout // 请求 vsync 信号
➜ mDisplayEventReceiver.scheduleVsync()
Choreographer.doFrame // 收到 vsync 信号
➜ doCallbacks(Choreographer.CALLBACK_INPUT, xxx);
➜ doCallbacks(Choreographer.CALLBACK_ANIMATION, xxx);
➜ doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, xxx);
➜ doCallbacks(Choreographer.CALLBACK_TRAVERSAL, xxx);
➜ ViewRootImpl.doTraversal
➜ performTraversals
➜ DecorView.dispatchAttachedToWindow
➜ Activity.onAttachedToWindow // cb.onAttachedToWindow
➜ performMeasure
➜ performLayout
➜ performDraw
➜ doCallbacks(Choreographer.CALLBACK_COMMIT, xxx);