分屏源码解析(1):分屏模式下主要的数据结构

分屏模式就是可以在recent中选取一个任务,然后调用startActivityFromRecent()向AMS请求在一个新的DOCKED stack中打开该任务对应的activity,再让recent app的画面重新启动,两个activity在屏幕的两侧,从而实现了分屏功能,因此AMS是如何创建DOCKED stack和WMS如何知道这两个activity的布局区域等问题就是该模式实现的关键了,所以要把这其中的数据结构搞清楚,才能去看流程怎么回事。下面依次介绍:

ActivityManagerService(AMS)中相关的类介绍:

  (1)Activity:这个就不用过多介绍了。

  (2)ActivityRecord:保存了关于特定Activity的信息,是AMS里的对于客户端Activity的一个映射,从该类中可以获取到客户端关于这个Activity的所有信息。

  (3)TaskRecord:一个TaskRcord对应了多个ActivityRecord,也就是说一个Task是包含了多个Activity的,用List保存:

/** List of all activities in the task arranged in history order */

final ArrayList<ActivityRecord> mActivities;

(4)ActivityStack:一个ActivityStack对应了多个TaskRecord,也是用List保存:

/**

* The back history of all previous (and possibly still

* running) activities.  It contains #TaskRecord objects.

*/

private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();

ps:这里就能看出来,activity的四种启动模式:standard,single_top,single_instance,single_task,是怎么被管理的了(不了解四种启动模式的话略过这段内容,有兴趣也可查阅其他资料)。比如standard模式,会无限制创建ActivityRecord,哪怕它已经有相同的实例了,因为它在对应的TaskRcord中会一直add你要启动的activity对应的ActivityRecord,所以按回退键的时候,Activity挨个出栈能看到所有启动过的Activity,而如果是single_task的话,启动的时候会先检查ActivityStack的mTaskHistory里是否已经有了这个TaskRecord,如果有就不会重新创建了,而是通过先remove掉管理它的Stack中List里面的TaskRecord,再add到List的尾部,从而实现了这个TaskRecord处于Stack的顶部,至于single_instance,那么就是一个TaskRecord对应了这个Activity的ActivityRecord,不会有其他的ActivityRecord被添加到这个TaskRecord中,即一对一的关系。

    (5)ActivityContainer:一个ActivityContainer对应了一个ActivityStack,该类提供了接口可以控制对应的ActivityStack。

      (6)ActivityDisplay:一个ActivityDisplay对应了多个ActivityStack,同样用List管理。

/** All of the stacks on this display. Order matters, topmost stack is in front of all other

* stacks, bottommost behind. Accessed directly by ActivityManager package classes */

final ArrayList<ActivityStack> mStacks = new ArrayList<>();



(7)ActivityStackSupervisor:该类听名字就知道是用于管理ActivityStack的。

WindowManagerService中的相关类:

  (1)Task:WMS中对应TaskRecord的类。

  (2)TaskStack:WMS中对应ActivityStack的类,用于管理Task,也就是说它的child是Task。

  (3)TaskWindowController:创建TaskRecord的时候,也会创建这个类的对象,用于管理Task。

  (4)StackWindowController:创建ActivityStack的时候,也会创建这个类的对象,用于TaskStack。

  (5)DisplayContent:管理所有TaskStack,也就是说它的child是TaskStack。

  (6)RootWindowContainer:所有window的根节点,从这里可以遍历到所有的window,它的child是DisplayContent。

  (7)WindowContainer:一个容器类的父类,TaskStack,DisplayContent,RootWindowContaniner均继承了它,它里面实现了一套管理child的方法,也就是提供了父节点管理子节点的方法。

  (8)WindowContainerController:控制容器类的父类,TaskWindowContainer,StackWindowController,AppWindowContainerController继承于它,同样也是提供了父节点管理子节点的方法。

    (9)AppWindowToken:一个应用(或者说一个Acitivty的画面)的一组Window。

    (10)AppWindowContainerController:管理AppWindowToken所有。

    (11)WindowState:WMS中window的概念,代表了一个window。

    如图:



从这里我们能看出来很重要的一点:AMS的Activity数据结构,在WMS中有类似的映射,其实AMS也有类似WindowContainer的容器结构,叫做ConfigurationContainer,ActivityStackSupervisor,ActivityStack,TaskRecord,ActivityRecord也均继承于它。

    在AMS的数据结构创建的时候,WMS也有映射的数据结构创建,比如我们创建DOCKED stack的时候,就会创建相应的StackWindowController,然后创建相应的TaskStack,然后添加到DisplayContent中(因为父节点是它)。


总结:AMS和WMS的交互是分屏模式的重点,要弄清楚内部发生了什么才能去实现新功能,上面的数据结构都是较为重要的,还有一些没有列举以后可以补充。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容