10:01 am
Wednesday, 22 June 2022 (GMT+8)
Time in Guangzhou, Guangdong Province, China


概述

基于Android 10分析ATMS.setTaskWindowingMode()流程。

ActivityTaskManagerService.setTaskWindowingMode

setTaskWindowingMode判断是否为请求的目标windowingMode是否为分屏模式并调用对应方法处理分屏。

否则验证权限后调用Task对应的ActivityStacksetWindowingMode()进行windowingMode变换。

ATMS.setTaskWindowingMode流程

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.setWindowingMode流程

ActivityStack.ConfigurationContainer.setWindowingMode

ActivityStack.setWindowingMode()通过ConfiguraionContainer体系,将设置的windowing mode转化为configuration changed设置到体系中的childern中。更新Stack内TaskRecordActivityRecord的configuration,应用新的windowing mode,计算应用bounds。最后通过ActivityRecord将merged conf更新到AppWindowToken

ActivityStack.ConfigurationContainer.setWindowingMode流程

ActivityStackSupervisor.scheduleUpdateMultiWindowMode

ActivityStack.setWindowingMode()流程中,TaskRecord.onConfigurationChanged()时,如果发生了多窗口模式的进入或退出,会调用ActivityStackSupervisor.scheduleUpdateMultiWindowMode()。它的主要作用是回调到App的onMultiWindowModeChanged()

ActivityStackSupervisor.scheduleUpdateMultiWindowMode

ActivityStack.resize

ActivityStack完成setWindowingMode()流程后,满足条件(bounds改变),就会执行resize()流程。其中,resize的目标bounds要么是EMPTY(match parent),要么是parent即TaskStack中获取的。resize()流程主要将ActivityStack及其children的Configuration按照resize bounds进行更新,并通过ActivityRecord更新AppWindowToken的merged configuration。

ActivityStack.resize流程

RootActivityContainer.resumeFocusedStacksTopActivities

ActivityStack.resize()以及WMS.continueSurfaceLayout()完成后,通过RootActivityContainer.ensureActivitiesVisible()计算Activity可见性,然后调用RootActivityContainer.resumeFocusedStacksTopActivities()。经过一系列准备后,resume了Activity并回调App的Activity.onResume()

RootActivityContainer.resumeFocusedStacksTopActivities流程

总结

setTaskWindowingMode()根据指定的不同的windowing mode,将ActivityStack以及其children设置到对应的configuration,并触发变换后,对窗口变换的实体处理Surface transaction,然后回调对应的应用层接口,最后完成窗口模式变换。