分屏模式就是可以在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的交互是分屏模式的重点,要弄清楚内部发生了什么才能去实现新功能,上面的数据结构都是较为重要的,还有一些没有列举以后可以补充。