概述

基于Android 10分析setRequestedOrientation()调用的流程。

ConfigurationContainer家族

  • ConfigurationContainer()体系结构

其中聚合关系是通过ConfigurationContainer.getParent()聚合的,集成关系则是各子类的继承关系。

ConfigurationContainer类家族和聚合关系

ConfigurationContainer组合

setRequestedOrientation调用

类图

setRequestedOrientation相关类图

setRequestedOrientation()触发Task.onDescendantOrientationChanged()

setRequestedOrientation流程

Task.onDescendantOrientationChanged()流程

Task.onDescendantOrientationChanged流程

ConfigurationContainer的四大Configuration

ConfigurationContainer包含了四个Configuration成员(以及一个用于计算Configuration时的中间临时载体mTmpConfig)。

1
2
3
4
5
6
7
8
9
10
11
// Contains requested override configuration settings applied to this configuration container.
private Configuration mRequestedOverrideConfiguration = new Configuration();

// Contains the requested override configuration with parent and policy constraints applied. This is the set of overrides that gets applied to the full and merged configurations.
private Configuration mResolvedOverrideConfiguration = new Configuration();

// Contains full configuration applied to this configuration container. Corresponds to full parent's config with applied mResolvedOverrideConfiguration.
private Configuration mFullConfiguration = new Configuration();

// Contains merged override configuration settings from the top of the hierarchy down to this particular instance. It is different from mFullConfiguration because it starts from topmost container's override config instead of global config.
private Configuration mMergedOverrideConfiguration = new Configuration();
名称 作用 描述
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()来重新计算前台应用,最后返回。

ATMS.updateDisplayOverrideConfigurationLocked流程

RootActivityContainer.onConfigurationChanged()流程

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

RAC.onConfChanged流程

WindowProcessController.onConfigurationChanged()流程

WindowProcessController的作用就是通过IApplicationThread将新的Configuration发送到ActivityThreadActivityThread通过ClientTransaction机制配合消息循环完成处理。

WPC.onConfigurationChanged流程

handleConfigurationChanged(): 接收Configuration Changed后ActivityThread的流程

ActivityThread将新的Configuration分发到三大组件(四大组件除BroadcastReceiver以外)。

ActivityThread.handleConfigurationChanged流程

Activity.onConfigurationChanged()

在上面,ActivityThread回调Activity.onConfigurationChan()。SDK内Activity类的onConfigurationChan()进行了重写,不是空实现。它内部的实现也是整个流程中重要的一环。

App必定需要调用super.onConfigurationChanged()来调用SDK中提供的基类的实现。因为在ActivityThread的实现中,会检查基类Activity.onConfigurationChanged()是否被调用,否则会抛出异常,愤怒地杀死App。

1
2
3
4
5
6
7
8
9
10
11
// ActivityThread.performActivityConfigurationChanged()
if (shouldChangeConfig) {
activity.mCalled = false;
activity.onConfigurationChanged(configToReport);
if (!activity.mCalled) {
throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
" did not call through to super.onConfigurationChanged()");
}
}
// 在Activity.onConfigurationChanged()的开头,设置了mCalled。
// 这个操作避免ActivityThread抛出异常

Activity.onConfiguration()的实现如下。首先发送changed Configuration到Fragments。然后发送到Window和ActionBar,分别回调它们的onConfigurationChanged()

Activity.onConfChanged相关类图

ATMS.performDisplayOverrideConfigUpdate()流程

performDisplayOverrideConfigUpdate()将更新后的Configuration发送到DisplayManagerService和DisplayDevice,并检查是否需要执行屏幕旋转动画。

ATMS.ensureConfigAndVisibilityAfterUpdate()流程

ensureConfigAndVisibilityAfterUpdate()用于检查Activity可见性。

ATMS.performDisplayOverrideConfigUpdate()流程

ATMS完成了所有工作,最后,调用WM.continueSurfaceLayout

总结

setRequestedOrientation()通过Binder触发ActivityRecord向上的整个ConfigurationContainer体系计算新的Configuration。并通过WindowProcessController触发各App的更新,回调onConfigurationChanged()。然后ensureConfigAndVisibilityAfterUpdate()计算各个Activity的可见性,最后继续WindowManager.continueSurfaceLayout()