Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

ndroid应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

 

        在WindowManagerService服务这一侧,每一个应用程序窗口,即每一个Activity组件,都有一个对应的WindowState对象,这个WindowState对象的成员变量mSurface同样是指向了一个Surface对象
,如图3所示:

  一个应用程序窗口分别位于应用程序进程和WindowManagerService服务中的两个Surface对象有什么区别呢?虽然它们都是用来操作位于SurfaceFlinger服务中的同一个Layer对象的,不过,它们的操作方式却不一样。具体来说,就是位于应用程序进程这一侧的Surface对象负责绘制应用程序窗口的UI,即往应用程序窗口的图形缓冲区填充UI数据,而位于WindowManagerService服务这一侧的Surface对象负责设置应用程序窗口的属性,例如位置、大小等属性。这两种不同的操作方式分别是通过C++层的Surface对象和SurfaceControl对象来完成的,因此,位于应用程序进程和WindowManagerService服务中的两个Surface对象的用法是有区别的。之所以会有这样的区别,是因为绘制应用程序窗口是独立的,由应用程序进程来完即可,而设置应用程序窗口的属性却需要全局考虑,即需要由WindowManagerService服务来统筹安排,例如,一个应用程序窗口的Z轴坐标大小要考虑它到的窗口类型以及它与系统中的其它窗口的关系。


Surface Surface

Surface  SurfaceControl
应用程序窗口在第一次显示的时候,就会请求WindowManagerService服务为其创建绘制表面。

当一个应用程序窗口被**并且它的视图对象创建完成之后,应用程序进程就会调用与其所关联的一个ViewRoot对象的成员函数requestLayout来请求对其UI进行布局以及显示。

WindowManagerService  

ViewRoot     request

 Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

 

public final class ViewRoot extends Handler implements ViewParent,
 public void requestLayout() {
 
 ViewRoot类是从Handler类继承下来的,用来处理应用程序窗口的UI布局和渲染等消息。

 public void scheduleTraversals() {

 private void performTraversals() {
 
         final View host = mView;
         
         
boolean cancelDraw = attachInfo.mTreeObserver.dispatchOnPreDraw();

attachInfo.mTreeObserver.dispatchOnPreDraw

        ViewRoot类的成员函数performTraversals的实现是相当复杂的,这里我们分析它的实现框架,在以后的文章中,我们再详细分析它的实现细节。

        在分析ViewRoot类的成员函数performTraversals的实现框架之前,我们首先了解ViewRoot类的以下五个成员变量:

        --mView:它的类型为View,但它实际上指向的是一个DecorView对象,用来描述应用程序窗口的*视图,这一点可以参考前面Android应用程序窗口(Activity)的视图对象(View)的创建过程分析一文。

        --mLayoutRequested:这是一个布尔变量,用来描述应用程序进程的UI线程是否需要正在被请求执行一个UI布局操作。

        --mFirst:这是一个布尔变量,用来描述应用程序进程的UI线程是否第一次处理一个应用程序窗口的UI。

        --mFullRedrawNeeded:这是一个布尔变量,用来描述应用程序进程的UI线程是否需要将一个应用程序窗口的全部区域都重新绘制。

        --mSurface:它指向一个Java层的Surface对象,用来描述一个应用程序窗口的绘图表面。

scheduleTraversals        performTraversals      

mView DecorView        

那么应用程序进程的UI线程就会调用另外一个成员函数relayoutWindow来请求WindowManagerService服务重新布局系统中的所有窗口。
ViewRoot
        performTraversals
      relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
      
       int relayoutResult = mWindowSession.relayout(
      过在重绘之前,会先询问一下那些注册到当前正在处理的应用程序窗口中的Tree Observer,即调用它们的成员函数dispatchOnPreDraw,看看它们是否需要取消接下来的重绘操作,这个询问结果保存在本地变量cancelDraw中。
      
      private final Surface mSurface = new Surface();  


实现了IWindowSession接口的Binder代理对象是由IWindowSession.Stub.Proxy类来描述的,
接下来我们就继续分析它的成员函数relayout的实现。
      
      IWindowSession IWindowSession.Stub.Proxy类
      
      interface IWindowSession {
    ......
 
    int relayout(IWindow window, in WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility,
            boolean insetsPending, out Rect outFrame, out Rect outContentInsets,
            out Rect outVisibleInsets, out Configuration outConfig,
            out Surface outSurface);
 
    ......
}

              这个接口定义在frameworks/base/core/java/android/view/IWindowSession.aidl文件
      
      Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析