更新DisplayContent的override configuration
// ActivityTaskManagerService.java
boolean updateDisplayOverrideConfigurationLocked(Configuration values,
ActivityRecord starting, boolean deferResume,
ActivityTaskManagerService.UpdateConfigurationResult result) {
int changes = 0;
boolean kept = true;
mAtmService.deferWindowLayout();
try {
if (values != null) {
if (mDisplayId == DEFAULT_DISPLAY) {
// 先去执行system server端从上至下的onConfigurationChanged的流程
changes = mAtmService.updateGlobalConfigurationLocked(values,
false /* initLocale */, false /* persistent */,
UserHandle.USER_NULL /* userId */, deferResume);
} else {
changes = performDisplayOverrideConfigUpdate(values, deferResume);
}
}
// 再去走app端的relaunch或onConfigurationChanged流程
kept = mAtmService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
} finally {
mAtmService.continueWindowLayout();
}
.......
return kept;
Relaunch Or schedule configuration change
先去ensure topActivity 确定该走Activity的relaunch还是onConfigurationChanged,再去ensure其他Activities
// ActivityTaskManagerService.java
boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
boolean kept = true;
final ActivityStack mainStack = mRootWindowContainer.getTopDisplayFocusedStack();
// mainStack is null during startup.
if (mainStack != null) {
if (changes != 0 && starting == null) {
starting = mainStack.topRunningActivity();
}
if (starting != null) {
// 先去确定top stack的top ativity的config
kept = starting.ensureActivityConfiguration(changes,
false /* preserveWindow */);
// 再去确定其他Activities
// And we need to make sure at this point that all other activities
// are made visible with the correct configuration.
mRootWindowContainer.ensureActivitiesVisible(starting, changes,
!PRESERVE_WINDOWS);
}
}
return kept;
}
AndroidManifest.xml 中对应的Activity如果配置了相关的configChanges,则不会去relaunch
// ActivityRecord.java
private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
int configChanged = info.getRealConfigChanged();
......
return (changes&(~configChanged)) != 0;
}
不走relaunch的Activity应当去scheduleConfigurationChanged
// ActivityRecord.java
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
boolean ignoreVisibility) {
......
if ((shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) && !notRelaunch) {
......
else {
relaunchActivityLocked(preserveWindow);
}
return false;
}
// 不relaunch 时需要去走 scheduleConfigurationChanged让Activity执行onConfiguration的流程
if (displayChanged) {
scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
} else {
scheduleConfigurationChanged(newMergedOverrideConfig);
}
stopFreezingScreenLocked(false);
return true;
}
处理topActivity的流程
shouldRelaunchLocked 为true走5,否则走6
- Relaunch
根据是否resume 分别post ResumeActivityItem 和 PauseActivityItem
void relaunchActivityLocked(boolean preserveWindow) {
......
boolean andResume = shouldBeResumed(null /*activeActivity*/);
......
if (andResume) {
EventLogTags.writeWmRelaunchResumeActivity(mUserId, System.identityHashCode(this),
task.mTaskId, shortComponentName);
} else {
EventLogTags.writeWmRelaunchActivity(mUserId, System.identityHashCode(this),
task.mTaskId, shortComponentName);
}
.....
try {
......
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
pendingNewIntents, configChangeFlags,
new MergedConfiguration(getProcessGlobalConfiguration(),
getMergedOverrideConfiguration()),
preserveWindow);
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(
getDisplay().mDisplayContent.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
transaction.addCallback(callbackItem);
transaction.setLifecycleStateRequest(lifecycleItem);
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
} catch (RemoteException e) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
}
......
}
- configuration change
post ActivityConfigurationChangeItem 到客户端
处理其他Activities的流程
shouldRelaunchLocked 为true走13,否则走14
app端执行Relaunch或onConfigurationChanged流程
以下两点同一个Activity只会执行其中一个流程,同样也是先执行topRunningActivity的流程,再依次执行其他页面的流程
Activity的重建
然后根据ResumeActivityItem和PauseActivityItem执行相应的生命周期,一般top Activity执行onResume,底下的执行onPause
onConfigurationChanged
Application的onConfigurationChanged回调
system server进程:
app进程: