Android setRequestedOrientation流程详解
概述
基于Android 10分析setRequestedOrientation()调用的流程。
ConfigurationContainer家族
- ConfigurationContainer()体系结构
其中聚合关系是通过ConfigurationContainer.getParent()聚合的,集成关系则是各子类的继承关系。


setRequestedOrientation调用
类图

setRequestedOrientation()触发Task.onDescendantOrientationChanged()

Task.onDescendantOrientationChanged()流程

ConfigurationContainer的四大Configuration
ConfigurationContainer包含了四个Configuration成员(以及一个用于计算Configuration时的中间临时载体mTmpConfig)。
1 | // Contains requested override configuration settings applied to this configuration container. |
| 名称 | 作用 | 描述 |
|---|---|---|
| mRequestedOverrideConfiguration | 记录该容器自身自行设置的或所对应的层级请求的Conf | onRequestedOverrideConfigurationChanged()回调时会修改该值,并触发onConfigurationChanged() |
| mResolvedOverrideConfiguration | 以mRequestedOverrideConfiguration为基础,按照容器定义的Conf策略(resolveOverrideConfiguration())修改后的结果 | resolveOverrideConfiguration()修改该值;可以理解为ConfContainer对requested override configuration的调整、修改、限制;ConfContainer的默认实现是不做修改,完全等同于mRequestedOverrideConfiguration |
| mFullConfiguration | ConfContainer实际的最终的Configuration | 在onConfiguration()时根据changed的conf和resolved conf进行修改,然后传递到子ConfContainer.onConfigurationChanged();由Global configuration changed触发,如setRequestedOrientation等屏幕旋转 |
| mMergedOverrideConfiguration | 从顶层层级的parent触发的传递下来的merged override conf | onMergedOverrideConfiguration()触发修改;由顶层的Container触发并向下层传递,区别于mFullConfiguration是global conf触发的 |
ATMS.updateDisplayOverrideConfigurationLocked()流程
ATMS调用updateGlobalConfigurationLocked(),它获取RootActivityContainer中的Configuration作为基础,根据传入的Configuration参数进行更新,然后增加Configuration序列号。向RootActivityContainer和全局所有WindowProcessController调用onConfigurationChanged()来更新Configuration。
最后通过ensureConfigAndVisibilityAfterUpdate()来重新计算前台应用,最后返回。

RootActivityContainer.onConfigurationChanged()流程
RootActivityContainer通过onConfigurationChanged()触发整个层级体系的处理,最终将Conf更新到ActivityRecord,将Merged Conf更新到AppWindowToken和它的Child WindowState中。

WindowProcessController.onConfigurationChanged()流程
WindowProcessController的作用就是通过IApplicationThread将新的Configuration发送到ActivityThread。ActivityThread通过ClientTransaction机制配合消息循环完成处理。

handleConfigurationChanged(): 接收Configuration Changed后ActivityThread的流程
ActivityThread将新的Configuration分发到三大组件(四大组件除BroadcastReceiver以外)。

Activity.onConfigurationChanged()
在上面,ActivityThread回调Activity.onConfigurationChan()。SDK内Activity类的onConfigurationChan()进行了重写,不是空实现。它内部的实现也是整个流程中重要的一环。
App必定需要调用super.onConfigurationChanged()来调用SDK中提供的基类的实现。因为在ActivityThread的实现中,会检查基类Activity.onConfigurationChanged()是否被调用,否则会抛出异常,愤怒地杀死App。
1 | // ActivityThread.performActivityConfigurationChanged() |
Activity.onConfiguration()的实现如下。首先发送changed Configuration到Fragments。然后发送到Window和ActionBar,分别回调它们的onConfigurationChanged()。

ATMS.performDisplayOverrideConfigUpdate()流程
performDisplayOverrideConfigUpdate()将更新后的Configuration发送到DisplayManagerService和DisplayDevice,并检查是否需要执行屏幕旋转动画。
ATMS.ensureConfigAndVisibilityAfterUpdate()流程
ensureConfigAndVisibilityAfterUpdate()用于检查Activity可见性。

ATMS完成了所有工作,最后,调用WM.continueSurfaceLayout
总结
setRequestedOrientation()通过Binder触发ActivityRecord向上的整个ConfigurationContainer体系计算新的Configuration。并通过WindowProcessController触发各App的更新,回调onConfigurationChanged()。然后ensureConfigAndVisibilityAfterUpdate()计算各个Activity的可见性,最后继续WindowManager.continueSurfaceLayout()。