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()
。