分屏模式就是可以在recent中選取一個任務(wù)锄弱,然后調(diào)用startActivityFromRecent()向AMS請求在一個新的DOCKED stack中打開該任務(wù)對應(yīng)的activity摆屯,再讓recent app的畫面重新啟動柳弄,兩個activity在屏幕的兩側(cè)玖媚,從而實現(xiàn)了分屏功能件已,因此AMS是如何創(chuàng)建DOCKED stack和WMS如何知道這兩個activity的布局區(qū)域等問題就是該模式實現(xiàn)的關(guān)鍵了桩蓉,所以要把這其中的數(shù)據(jù)結(jié)構(gòu)搞清楚增拥,才能去看流程怎么回事破婆。下面依次介紹:
ActivityManagerService(AMS)中相關(guān)的類介紹:
? (1)Activity:這個就不用過多介紹了涮总。
? (2)ActivityRecord:保存了關(guān)于特定Activity的信息,是AMS里的對于客戶端Activity的一個映射祷舀,從該類中可以獲取到客戶端關(guān)于這個Activity的所有信息瀑梗。
? (3)TaskRecord:一個TaskRcord對應(yīng)了多個ActivityRecord,也就是說一個Task是包含了多個Activity的裳扯,用List保存:
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
(4)ActivityStack:一個ActivityStack對應(yīng)了多個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哟忍,是怎么被管理的了(不了解四種啟動模式的話略過這段內(nèi)容狡门,有興趣也可查閱其他資料)。比如standard模式锅很,會無限制創(chuàng)建ActivityRecord其馏,哪怕它已經(jīng)有相同的實例了,因為它在對應(yīng)的TaskRcord中會一直add你要啟動的activity對應(yīng)的ActivityRecord爆安,所以按回退鍵的時候叛复,Activity挨個出棧能看到所有啟動過的Activity,而如果是single_task的話扔仓,啟動的時候會先檢查ActivityStack的mTaskHistory里是否已經(jīng)有了這個TaskRecord褐奥,如果有就不會重新創(chuàng)建了,而是通過先remove掉管理它的Stack中List里面的TaskRecord翘簇,再add到List的尾部撬码,從而實現(xiàn)了這個TaskRecord處于Stack的頂部,至于single_instance版保,那么就是一個TaskRecord對應(yīng)了這個Activity的ActivityRecord呜笑,不會有其他的ActivityRecord被添加到這個TaskRecord中夫否,即一對一的關(guān)系。
? ? (5)ActivityContainer:一個ActivityContainer對應(yīng)了一個ActivityStack叫胁,該類提供了接口可以控制對應(yīng)的ActivityStack凰慈。
? ? ? (6)ActivityDisplay:一個ActivityDisplay對應(yīng)了多個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中的相關(guān)類:
? (1)Task:WMS中對應(yīng)TaskRecord的類。
? (2)TaskStack:WMS中對應(yīng)ActivityStack的類谤民,用于管理Task堰酿,也就是說它的child是Task。
? (3)TaskWindowController:創(chuàng)建TaskRecord的時候张足,也會創(chuàng)建這個類的對象触创,用于管理Task。
? (4)StackWindowController:創(chuàng)建ActivityStack的時候为牍,也會創(chuàng)建這個類的對象哼绑,用于TaskStack。
? (5)DisplayContent:管理所有TaskStack碉咆,也就是說它的child是TaskStack抖韩。
? (6)RootWindowContainer:所有window的根節(jié)點,從這里可以遍歷到所有的window疫铜,它的child是DisplayContent茂浮。
? (7)WindowContainer:一個容器類的父類,TaskStack壳咕,DisplayContent席揽,RootWindowContaniner均繼承了它,它里面實現(xiàn)了一套管理child的方法谓厘,也就是提供了父節(jié)點管理子節(jié)點的方法幌羞。
? (8)WindowContainerController:控制容器類的父類,TaskWindowContainer竟稳,StackWindowController属桦,AppWindowContainerController繼承于它,同樣也是提供了父節(jié)點管理子節(jié)點的方法他爸。
? ? (9)AppWindowToken:一個應(yīng)用(或者說一個Acitivty的畫面)的一組Window聂宾。
? ? (10)AppWindowContainerController:管理AppWindowToken所有。
? ? (11)WindowState:WMS中window的概念诊笤,代表了一個window系谐。
? ? 如圖:
從這里我們能看出來很重要的一點:AMS的Activity數(shù)據(jù)結(jié)構(gòu),在WMS中有類似的映射盏混,其實AMS也有類似WindowContainer的容器結(jié)構(gòu)蔚鸥,叫做ConfigurationContainer,ActivityStackSupervisor许赃,ActivityStack止喷,TaskRecord,ActivityRecord也均繼承于它混聊。
? ? 在AMS的數(shù)據(jù)結(jié)構(gòu)創(chuàng)建的時候弹谁,WMS也有映射的數(shù)據(jù)結(jié)構(gòu)創(chuàng)建,比如我們創(chuàng)建DOCKED stack的時候句喜,就會創(chuàng)建相應(yīng)的StackWindowController预愤,然后創(chuàng)建相應(yīng)的TaskStack,然后添加到DisplayContent中(因為父節(jié)點是它)咳胃。
總結(jié):AMS和WMS的交互是分屏模式的重點植康,要弄清楚內(nèi)部發(fā)生了什么才能去實現(xiàn)新功能,上面的數(shù)據(jù)結(jié)構(gòu)都是較為重要的展懈,還有一些沒有列舉以后可以補充销睁。