-
public void scheduleTraversals() {
-
if (!mTraversalScheduled) {
-
mTraversalScheduled = true;
-
sendEmptyMessage(DO_TRAVERSAL);
-
}
-
}
我们看看跨进程的那个调用。sWindowSession.add。它的最终实现在WindowManagerService中。
[—>WindowSession::add()]
-
public int add(IWindow window, WindowManager.LayoutParams attrs,
-
int viewVisibility, Rect outContentInsets) {
-
return addWindow(this, window, attrs, viewVisibility, outContentInsets);
-
}
WindowSession是个内部类,会调用外部类的addWindow。
这个函数巨复杂无比,但是我们的核心目标是找到创建显示相关的部分。所以,最后精简的话就简单了。
[—>WindowManagerService:: addWindow]
-
public int addWindow(Session session, IWindow client,
-
WindowManager.LayoutParams attrs, int viewVisibility,
-
Rect outContentInsets) {
-
//创建一个WindowState,这个又是什么玩意儿呢?
-
win = new WindowState(session, client, token,
-
attachedWindow, attrs, viewVisibility);
-
win.attach();
-
return res;
-
}
WindowState类中有一个和Surface相关的成员变量,叫SurfaceSession。它会在attach函数中被创建。SurfaceSession嘛,就和SurfaceFlinger有关系了。我们待会看。
好,我们知道ViewRoot创建及调用add后,我们客户端的View系统就和WindowManagerService建立了牢不可破的关系。
另外,我们知道ViewRoot是一个handler,而且刚才我们调用了requestLayout,所以接下来消息循环下一个将调用的就是ViewRoot的handleMessage。
-
public void handleMessage(Message msg) {
-
switch (msg.what) {
-
case DO_TRAVERSAL:
-
performTraversals();
performTraversals更加复杂无比,经过我仔细挑选,目标锁定为下面几个函数。当然,后面我们还会回到performTraversals,不过我们现在更感兴趣的是Surface是如何创建的。
-
private void performTraversals() {
-
// cache mView since it is used so much below…
-
final View host = mView;
-
boolean initialized = false;
-
boolean contentInsetsChanged = false;
-
boolean visibleInsetsChanged;
-
try {
-
//ViewRoot也有一个Surface成员变量,叫mSurface,这个就是代表SurfaceFlinger的客户端
-
//ViewRoot在这个Surface上作画,最后将由SurfaceFlinger来合成显示。刚才说了mSurface还没有什么内容。
-
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
[---->ViewRoot:: relayoutWindow()]
-
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
-
boolean insetsPending) throws RemoteException {
-
//relayOut是跨进程调用,mSurface做为参数传进去了,看来离真相越来越近了呀!
-
int relayoutResult = sWindowSession.relayout(
-
mWindow, params,
-
(int) (mView.mMeasuredWidth * appScale + 0.5f),
-
(int) (mView.mMeasuredHeight * appScale + 0.5f),
-
viewVisibility, insetsPending, mWinFrame,
-
mPendingContentInsets, mPendingVisibleInsets,
-
mPendingConfiguration, mSurface); mSurface做为参数传进去了。
-
}
我们赶紧转到WindowManagerService去看看吧。
-
public int relayoutWindow(Session session, IWindow client,
-
WindowManager.LayoutParams attrs, int requestedWidth,
-
int requestedHeight, int viewVisibility, boolean insetsPending,
-
Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
-
Configuration outConfig, Surface outSurface){
-
…
-
try {
-
//看到这里,我内心一阵狂喜,有戏,太有戏了!
-
//其中win是我们最初创建的WindowState!
-
Surface surface = win.createSurfaceLocked();
-
if (surface != null) {
-
//先创建一个本地surface,然后把传入的参数outSurface copyFrom一下
-
outSurface.copyFrom(surface);
-
win.mReportDestroySurface = false;
-
win.mSurfacePendingDestroy = false;
-
} else {
-
outSurface.release();
-
}
-
}
-
}
[—>WindowState::createSurfaceLocked]
-
Surface createSurfaceLocked() {
-
try {
-
mSurface = new Surface(
-
mSession.mSurfaceSession, mSession.mPid,
-
mAttrs.getTitle().toString(),
-
0, w, h, mAttrs.format, flags);
-
}
-
Surface.openTransaction();
这里