概述
深入理解Android中Surface系统,主要是弄清楚两个问题:
# 应用程序和Surface的关系。
# Surface和SurfaceFlinger的关系。
不论是使用Skia绘制二维图像,还是使用OpenGL绘制三维图像,最终Application都要和Surface交互。Surface就像是UI的画布, 而App则像是在Surface上作画。
Surface向SurfaceFlinger提供数据,而SurfaceFlinger则混合数据。
一个Activity的显示
Activity的创建
zygote在响应请求后,会fork一个子进程,这个子进程是App对应的进程,它的入口函数时ActivityThread的main函数。ActivityThread类中有一个handleLaunchActivity函数,它就是创建Activity的地方。在handleLaunchActivity函数中调用了performLaunchActivity和handleResumeActivity函数,这个函数很关键。
performLaunchActivity函数的作用是:
# 根据类名以Java反射的方法创建一个Activity。
# 调用Activity的onCreate函数,开始在SDK中大书特书Activity的生命周期。
handleResumeActivity的作用
# 通过activity.getWindow()获得一个View对象。
# 获得一个WindowManager对象。
# 把创建的View对象加入到ViewManager中。
这里Activity和UI部分开始关联上了。答案就是在onCreate函数中,Activity一般都在这个函数中通过setContentView设置UI界面。
setContentView分析,代码:
public void setContentView(View view){
getWindow().setContentView();
}
public Window getWindow(){
return mWindow;
}
解释: Window是一个抽象基类,用于控制顶层窗口的外观和行为。作为顶层窗口,会绘制背景和标题栏,默认的按键处理等。这个Window会作为顶层的View加入到WindowManager中。
View是一个基本的UI单元,占据屏幕的一块矩形区域,可用于绘制,并能处理事件。
疑问:Window是抽象类,它实际的对象到底是什么类型?
WindowManager究竟是什么?
** Window对象是通过PolicyManager来创建的,Window类的具体实现类时PhoneWindow类。
** mWindowManager成员变量的真实类型是LocalWindowManager,LocalWindowManager和WindowManagerImpl都实现了WindowManager接口。这里采用了Proxy模式,表明LocalWindowManager将把它的工作委托给WindowManagerImpl来完成。
在setContentView方法中的installDecor()内部,创建了一个mDecor对象,这个对象时DecorView类型,从FrameLayout派生而来。这个类是PhoneWindow的包装类。在这个类中添加标题栏和内容视图。
重回handleResumeActivity
handleResumeActivity最终调用的是addView方法。在addView中创建了一个ViewRoot对象,这个ViewRoot对象将之前创建的DecorView添加进来。
## ViewRoot继承了Handler类,重写了handleMessage方法,能处理消息。
## ViewRoot有一个成员变量叫做mSurface,它是Surface类型。
## ViewRoot还有一个W类型的mWindow和一个View类型的mView变量。W是ViewRoot定义的一个静态内部类:
static class W extends IWindow.Stub
这个类将参与Binder的通信。
Surface类
概念: 有一块Raw Buffer, 至于是内存还是显存,不必管它。
Surface操作这块Raw Buffer。
Screen compositor管理这块Raw Buffer。
WindowManagerService由System_Server进程启动,SurfaceFlinger服务也在这个进程中。
ViewRoot的setView函数做了三件事:
# 保存传入的view参数为mView,这个mView指向PhoneWindow的DecorView。
# 调用requestLayout。
# 调用IWindowSession的add函数,这是一个跨进程的Binder通信,但是第一个参数是mWindw,它是W类型,从IWindow.stub派生。