我们知道DecorView与ViewRootImpl之间是一一对应的关系。ViewRootImpl的成员变量mView保存DecorView的实例。
DecorView是整个Activity的View Tree的根视图,整个Activity的显示就是从DecorView开始将整颗ViewTree中的可视部分绘制到SurfaceFlinger提供的Surface上。
ViewRootImpl中包含一个Surface类型的成员变量mSurface。
在ViewRootImpl的draw()函数中可以看到,Activity的view tree绘制从DecorView开始触发,绘制在了ViewRootImpl的mSurface lock得到的一块Cavas上。
所以Activity的DecorView是与ViewRootImpl的mSurface直接关联的。
所以本文的重点就是分析ViewRootImpl的mSurface成员变量是怎样与SurfaceFlinger的Surface建立关联的。
具体的分析过程可分为两步。
第一步,我们先弄清楚ViewRootImpl中的IWindowSession,IWindow类型的成员变量和WindowManagerService中维护的WindowState类型的成员变量之间的关系。
这里先给出结论:
ViewRootImpl与WindowManagerService之间要进行双向通信。
ViewRootImpl通过IWindowSession与WindowManagerService通信。
WindowManagerService通过IWindow与ViewRootImpl通信。
IWindowSession的具体实现类Session在WindowManagerService中的实例代表一个需要与WindowManagerService通信的客户端。
WindowManagerService通过管理WindowState来管理客户端的Window实例。
WindowState实例中包含代表客户端窗口的IWindow实例,和代表客户端的Session实例。
WindowState在WindowManagerService中就代表客户端的Window实例。
WindowState与客户端的IWindow,IWindowSession是一一对应的关系。WindowManagerService的HashMap<IBinder, WindowState> mWindowMap结构
用于存储客户端窗口对象IWindow和WindwoManaerService中的创建的WindowState之间的对应关系。使客户端的IWindow和WindowState一一对应起来。可以通过客户端的IWindow找到WindowManagerService中对应的WindowState.
下面是详细的分析过程。1)ViewRootImpl,IWindowSession,WindowManagerService之间关系的建立过程
这个过程开始于ViewRootImpl的构造函数调用getWindowSession().
ViewRootImpl.getWindowSession()调用Display.getWindowManager()得到的WindowManagerService的本地代理类IWindowManager.Stub.Proxy.
这里涉及到java层Binder架构。先不关注。
这个过程完成后WindowManagerService中创建了一个Session实例,
这个Session实例的本地Binder代理类IWindowSession.Stub.Proxy保存在ViewRootImpl的IWindowSession类型成员变量sWindowSession。
这个过程结束后,ViewRootImpl就可以通过IWindowSession与WindowManagerService进行通信了。因为IWindowSession的在WindowManagerService中的本地实例Session包含创建它的WindowManagerService实例。
ViewRootImpl通过IWindowSession调用的接口都会通过Session转换为对WindowManagerService的调用。
注意此时WindowMangerService还没有与代表客户端的Session实例建立关联。
2)ViewRootImpl,IWindow,WindowManagerService之间关系的建立过程
这个过程开始于ViewRootImpl的setView()方法中,这个方法的调用时机在Android4.0.1 Activity的Window与DecorView关系建立过程分析中已经介绍了。
ViewRootImpl的mWindow的类型是ViewRootImpl的内置类class W extends IWindow.Stub。
IWindow接口是提供给WindowMangerService回调的,用来通知客户端窗口一些事情发生了。
ViewRootImpl.setView()通过IWindowSession.add()调用到WindowManagerService的addWindow().
WindowManagerService在创建完WindowState后会调用它的attach()函数,WindowState.attach()函数的执行会产生两个效果。
一个是代表客户端的Session创建SurfaceSession.
另一个是使代表客户端的Session加入到WindowManagerService的mSession结构中。此时WindowManagerService与代表客户端的Session之间才建立起关联。
第二步,ViewRootImpl的mSurface成员变量与SurfaceFlinger创建的Surface之间的关系建立过程
这个过程从ViewRootImpl的performTraversals()函数开始。ViewRootImpl.relayoutWindow()会调用IWindowSession.Stub.Proxy.relayout()接口同时将自身的mSurface作为参数传进去。
IWindowSession.Stub.Proxy.relayout()最终会调用Session.relayout().Session.relayout()会调用WindowManagerService.relayoutWindow().
WindowManagerService.relayoutWindow()会根据传进来的参数(客户端的Session,IWindow)调用windowForClientLocked查找与之匹配(客户端的Session,IWindow)的WindowState.
前面提过,客户端的Session,IWindow和WindowManagerService中维护的WindowState是一一对应的。
查到这个WindowState后,就会调用WindowState.createSurfaceLocked()。
WindowState.createSurfaceLocked()在创建Surface时将Session中的SurfaceSession作为参数传给了java层的Surface构造函数。
java层的Surface构造函数会调用native函数的init(),这个函数是最终导致SurfaceFlinger中的Surface的创建
这个SurfaceFlinger中创建出来的Surface在java层的表示就是WindowState的mSurface。
WindowManagerService.relayoutWindow()在调用完WindowState.createSurfaceLocked()后,会调用outSurface.copyFrom(win.mSurface);
其中outSurface就是ViewRootImpl调用IWindowSession.Stub.Proxy.relayout()时传进来的成员变量mSurface.
至此,ViewRootImpl中的mSurface就与SurfaceFlinger创建的Surface关联起来了。
接下来看下ViewRootImpl.performTraversals()的调用过程。
ViewRootImpl中很多地方都会调用scheduleTraversals(),这个函数会触发重绘动作。
scheduleTraversals()发送DO_TRAVERSAL类型的消息。
handleMessage()处理DO_TRAVERSAL类型消息时调用performTraversals().
performTraversals()也会调用scheduleTraversals().
本文涉及的主要类的类图如下。