Android setTaskWindowingMode流程详解
10:01 am
Wednesday, 22 June 2022 (GMT+8)
Time in Guangzhou, Guangdong Province, China
- 概述
- ActivityTaskManagerService.setTaskWindowingMode
- ActivityStack.setWindowingMode
- ActivityStack.resize
- RootActivityContainer.resumeFocusedStacksTopActivities
- 总结
概述
基于Android 10分析ATMS.setTaskWindowingMode()
流程。
ActivityTaskManagerService.setTaskWindowingMode
setTaskWindowingMode
判断是否为请求的目标windowingMode
是否为分屏模式并调用对应方法处理分屏。
否则验证权限后调用Task对应的ActivityStack
的setWindowingMode()
进行windowingMode
变换。
ActivityStack.setWindowingMode
ActivityStack
会检查windwoingMode、修改windowingMode,并且通过触发ConfigurationContainer
体系的onConfigurationChanged()
取得体系计算或覆盖的windowingMode。根据这个windowingMode将自身乃至整个ConfigurationContainer
中低层级的children的windowingMode通过setWindowingMode()
修改,并resize()
到指定大小。
最后,会计算可见的Activity并resume top running Activity。
其中,比较细节的部分是setWindowingMode()
部分,触发children的ConfigurationContainer
体系的onConfigurationChanged()
,通过这个流程来影响child的conf。resize()
部分,也会触发changed。RootActivityContainer
.resumeFocusedStacksTopActivities()
最终还是会回调ActivityStack
来resume stack内的Activity。
ActivityStack.ConfigurationContainer.setWindowingMode
ActivityStack.setWindowingMode()
通过ConfiguraionContainer
体系,将设置的windowing mode转化为configuration changed设置到体系中的childern中。更新Stack内TaskRecord
、ActivityRecord
的configuration,应用新的windowing mode,计算应用bounds。最后通过ActivityRecord
将merged conf更新到AppWindowToken
。
ActivityStackSupervisor.scheduleUpdateMultiWindowMode
在ActivityStack.setWindowingMode()
流程中,TaskRecord.onConfigurationChanged()
时,如果发生了多窗口模式的进入或退出,会调用ActivityStackSupervisor.scheduleUpdateMultiWindowMode()
。它的主要作用是回调到App的onMultiWindowModeChanged()
。
ActivityStack.resize
ActivityStack
完成setWindowingMode()
流程后,满足条件(bounds改变),就会执行resize()
流程。其中,resize的目标bounds要么是EMPTY(match parent),要么是parent即TaskStack中获取的。resize()
流程主要将ActivityStack
及其children的Configuration按照resize bounds进行更新,并通过ActivityRecord
更新AppWindowToken
的merged configuration。
RootActivityContainer.resumeFocusedStacksTopActivities
ActivityStack.resize()
以及WMS.continueSurfaceLayout()
完成后,通过RootActivityContainer.ensureActivitiesVisible()
计算Activity可见性,然后调用RootActivityContainer.resumeFocusedStacksTopActivities()
。经过一系列准备后,resume了Activity并回调App的Activity.onResume()
。
总结
setTaskWindowingMode()
根据指定的不同的windowing mode,将ActivityStack
以及其children设置到对应的configuration,并触发变换后,对窗口变换的实体处理Surface transaction,然后回调对应的应用层接口,最后完成窗口模式变换。