前言
上一篇我们简单介绍了应用的窗口属性WindowConfiguration这个类,该类存储了当前窗口的显示区域、屏幕的旋转方向、窗口模式等参数,当设备屏幕发生旋转的时候就是通过该类将具体的旋转数据传递给应用的、而应用在加载资源文件的时候也会结合该类的AppBounds属性,自动加载特定分辨率的资源文件。而在这些属性发生变化之后,系统一般都是在onConfigurationChanged方法中作出响应的,这篇文章我们将会结合系统深浅主题发生切换到时候,新的系统配置是如何通过onConfigurationChanged回调给Activity的。
一、用户行为触发深浅模式主题切换
这里我们以下拉状态栏的快捷按钮深色主题切换为切入口来做具体源码分析,我们点击该按钮,首先会触发UiModeNightTile的handleClick方法。
1.1 SystemUI阶段
frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
ConfigurationController.ConfigurationListener,
BatteryController.BatteryStateChangeCallback {
private UiModeManager mUiModeManager;
@Override
protected void handleClick(@Nullable View view) {
if (getState().state == Tile.STATE_UNAVAILABLE) {
return;
}
boolean newState = !mState.value;
//注释1
mUiModeManager.setNightModeActivated(newState);
refreshState(newState);
}
}
在注释1处调用UiModeManager的setNightModeActivated方法。
1.2 UiModeManager阶段
frameworks/base/core/java/android/app/UiModeManager.java
public class UiModeManager {
private IUiModeManager mService;
UiModeManager(Context context) throws ServiceNotFoundException {
mService = IUiModeManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.UI_MODE_SERVICE));
mContext = context;
}
/**
* 激活当前用户的夜间模式UI视图
*/
public boolean setNightModeActivated(boolean active) {
if (mService != null) {
try {
//注释1,调用UiModeManagerService的setNightModeActivated方法
return mService.setNightModeActivated(active);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return false;
}
}
在注释1处调用UiModeManagerService的setNightModeActivated方法。
1.3 UiModeManagerService阶段
frameworks/base/services/core/java/com/android/server/UiModeManagerService.java
final class UiModeManagerService extends SystemService {
private Configuration mConfiguration = new Configuration();
@Override
public boolean setNightModeActivated(boolean active) {
...代码省略...
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
//自动、自定义的主题切换
if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) {
unregisterScreenOffEventLocked();
mOverrideNightModeOff = !active;
mOverrideNightModeOn = active;
mOverrideNightModeUser = mCurrentUser;
persistNightModeOverrides(mCurrentUser);
} else if (mNightMode == UiModeManager.MODE_NIGHT_NO && active) {
//夜间模式
mNightMode = UiModeManager.MODE_NIGHT_YES;
} else if (mNightMode == UiModeManager.MODE_NIGHT_YES
&& !active) {
//日间模式
mNightMode = UiModeManager.MODE_NIGHT_NO;
}
//注释1,更新Configuration
updateConfigurationLocked();
//注释2,应用Configuration
applyConfigurationExternallyLocked();
//为当前用户对应的Secure添加配置信息
persistNightMode(mCurrentUser);
return true;
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
private void updateConfigurationLocked() {
...代码省略...
if (!mHoldingConfiguration && (!mWaitForScreenOff || mPowerSave)) {
//将新的UIMode赋值给mConfiguration
mConfiguration.uiMode = uiMode;
}
}
private void applyConfigurationExternallyLocked() {
if (mSetUiMode != mConfiguration.uiMode) {
mSetUiMode = mConfiguration.uiMode;
//清除窗口户的快照缓存
mWindowManager.clearSnapshotCache();
try {
//注释3,调用ATMS的updateConfiguration方法,更新当前用户对应的Configuration
ActivityTaskManager.getService().updateConfiguration(mConfiguration);
} catch (RemoteException e) {
Slog.w(TAG, "Failure communicating with activity manager", e);
} catch (SecurityException e) {
Slog.e(TAG, "Activity does not have the ", e);
}
}
}
}
在注释1处调用updateConfigurationLocked方法,该方法会将新的UIMode赋值给mConfiguration;在注释2处调用
applyConfigurationExternallyLocked方法,该方法内部也就是注释3处,会调用ATMS的updateConfiguration方法,将当前用户包含了新UiMode的Configuration同步给系统中的其他模块和应用。
二、ActivityTaskManagerService通知ActivityThread
2.1 ActivityTaskManagerService阶段
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public boolean updateConfiguration(Configuration values) {
mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
synchronized (mGlobalLock) {
if (mWindowManager == null) {
Slog.w(TAG, "Skip updateConfiguration because mWindowManager isn't set");
return false;
}
if (values == null) {
//从WMS中获取当前系统默认屏幕设备对应的配置信息
values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
}
mH.sendMessage(PooledLambda.obtainMessage(
ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
DEFAULT_DISPLAY));
final long origId = Binder.clearCallingIdentity();
try {
if (values != null) {
Settings.System.clearConfiguration(values);
}
//注释1,继续调用updateConfigurationLocked,更新配置信息
updateConfigurationLocked(values, null, false, false /* persistent */,
UserHandle.USER_NULL, false /* deferResume */,
mTmpUpdateConfigurationResult);
return mTmpUpdateConfigurationResult.changes != 0;
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
boolean initLocale, boolean persistent, int userId, boolean deferResume,
ActivityTaskManagerService.UpdateConfigurationResult result) {
int changes = 0;
boolean kept = true;
deferWindowLayout();
try {
if (values != null) {
//注释2,更新全局配置
changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId);
}
if (!deferResume) {
//注释4,更新后确保配置和可见性
kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
}
} finally {
continueWindowLayout();
}
if (result != null) {
result.changes = changes;
result.activityRelaunched = !kept;
}
return kept;
}
int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
boolean persistent, int userId) {
...代码省略...
SparseArray<WindowProcessController> pidMap = mProcessMap.getPidMap();
for (int i = pidMap.size() - 1; i >= 0; i--) {
final int pid = pidMap.keyAt(i);
final WindowProcessController app = pidMap.get(pid);
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Update process config of %s to new "
+ "config %s", app.mName, mTempConfig);
//注释3,调用app的onConfigurationChanged方法
app.onConfigurationChanged(mTempConfig);
}
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::broadcastGlobalConfigurationChanged,
mAmInternal, changes, initLocale);
mH.sendMessage(msg);
mRootWindowContainer.onConfigurationChanged(mTempConfig);
return changes;
}
}
注释1处ATMS的updateConfiguration方法继续调用updateConfigurationLocked;
注释2处调用updateGlobalConfigurationLocked方法更新当前系统的全局配置;
注释3获取当前系统中的每一个窗口管理者,调用app.onConfigurationChanged方法,告知他们系统配置发生了变化。
2.2 WindowProcessController阶段
frameworks/base/services/core/java/com/android/server/wm/WindowProcessController.java
public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
implements ConfigurationContainerListener {
private final ActivityTaskManagerService mAtm;
@Override
public void onConfigurationChanged(Configuration newGlobalConfig) {
super.onConfigurationChanged(newGlobalConfig);
//调用updateConfiguration方法
updateConfiguration();
}
private void updateConfiguration() {
final Configuration config = getConfiguration();
if (mLastReportedConfiguration.diff(config) == 0) {
if (Build.IS_DEBUGGABLE && mHasImeService) {
Slog.w(TAG_CONFIGURATION, "Current config: " + config
+ " unchanged for IME proc " + mName);
}
return;
}
if (mPauseConfigurationDispatchCount > 0) {
mHasPendingConfigurationChange = true;
return;
}
//调用dispatchConfiguration方法
dispatchConfiguration(config);
}
void dispatchConfiguration(Configuration config) {
mHasPendingConfigurationChange = false;
if (mThread == null) {
if (Build.IS_DEBUGGABLE && mHasImeService) {
Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName
+ ": no app thread");
}
return;
}
try {
config.seq = mAtm.increaseConfigurationSeqLocked();
//注释1,获取ClientLifecycleManager实例
//调用其scheduleTransaction方法,并传入ConfigurationChangeItem对象实例
mAtm.getLifecycleManager().scheduleTransaction(mThread,
ConfigurationChangeItem.obtain(config));
setLastReportedConfiguration(config);
} catch (Exception e) {
Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
}
}
}
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private final ClientLifecycleManager mLifecycleManager;
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
}
>frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
class ClientLifecycleManager {
void scheduleTransaction(@NonNull IApplicationThread client,
@NonNull ClientTransactionItem callback) throws RemoteException {
final ClientTransaction clientTransaction = transactionWithCallback(client,
null /* activityToken */, callback);
//调用scheduleTransaction方法
scheduleTransaction(clientTransaction);
}
private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
IBinder activityToken, @NonNull ClientTransactionItem callback) {
//获取clientTransaction 对象实例
final clientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
clientTransaction.addCallback(callback);
return clientTransaction;
}
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
//调用ClientTransaction的scheduleTransaction
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
}
>frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
public class ClientTransaction implements Parcelable, ObjectPoolItem {
private IApplicationThread mClient;
public void schedule() throws RemoteException {
//注释2,调用IApplicationThread的scheduleTransaction方法
mClient.scheduleTransaction(this);
}
}
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//注释3,调用scheduleTransaction方法,该方法位于父类ClientTransactionHandler中
ActivityThread.this.scheduleTransaction(transaction);
}
}
}
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
//注释3,调用sendMessage
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
final H mH = new H();
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
class H extends Handler {
public static final int EXECUTE_TRANSACTION = 159;
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
//注释4,调用TransactionExecutor的execute方法
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
}
}
}
public class TransactionExecutor {
public void execute(ClientTransaction transaction) {
...代码省略...
//继续调用executeCallbacks方法
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
public void executeCallbacks(ClientTransaction transaction) {
...代码省略...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...代码省略...
//注释4,调用每个ClientTransactionItem对象实例的execute方法
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
...代码省略...
}
}
}
public class ConfigurationChangeItem extends ClientTransactionItem {
//获取ConfigurationChangeItem实例对象
public static ConfigurationChangeItem obtain(Configuration config) {
ConfigurationChangeItem instance = ObjectPool.obtain(ConfigurationChangeItem.class);
if (instance == null) {
instance = new ConfigurationChangeItem();
}
instance.mConfiguration = config;
return instance;
}
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
//注释5,这里会触发ActivityThreade的handleConfigurationChanged方法
client.handleConfigurationChanged(mConfiguration);
}
}
public class ActivityRelaunchItem extends ActivityTransactionItem {
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
if (mActivityClientRecord == null) {
if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
return;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
//注释6,调用ActivityThread的handleRelaunchActivity方法
client.handleRelaunchActivity(mActivityClientRecord, pendingActions);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
//注释7,调用ActivityThread的handleActivityConfigurationChanged方法
client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
对以上代码做个简单概述。
- WindowProcessController的onConfigurationChanged方法经过层层调用,最终会在注释1处触发一个关键调用,调用ATM的getLifecycleManager方法获取ClientLifecycleManager实例,并调用该对象的scheduleTransaction方法,传入ConfigurationChangeItem对象实例作为参数,这个我们后面还会提到。
- ClientLifecycleManager的scheduleTransaction方法继续往下走,会在注释2处触发IApplicationThread的scheduleTransaction方法,该方法位于父类ClientTransactionHandler中,在注释3处调用sendMessage方法,发送ActivityThread.H.EXECUTE_TRANSACTION的消息类型,最终会走到注释4处,调用TransactionExecutor的execute方法。
- TransactionExecutor的execute方法继续调用executeCallbacks方法,然后在注释5处调用每个ClientTransactionItem对象实例的execute方法,我们在前面注释1处提过到过ConfigurationChangeItem对象作为参数。
- 默认情况下在UIMode发生切换的时候,这里的ClientTransactionItem对象实例其实是ActivityRelaunchItem,执行execute方法,也就是注释6处会触发ActivityThread的handleRelaunchActivity,最终会触发Activity的onCreate方法。
- 如果Activity页面不希望UIMode发生切换的时候重新执行onCreate方法,这里的ClientTransactionItem对象实例其实是ActivityConfigurationChangeItem,执行execute方法,也就是注释7处会触发ActivityThread的handleActivityConfigurationChanged,最终会触发Activity的onConfigurationChanged方法。
三、ActivityThread通知应用
3.1 回调Activity的onCreate方法
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
@Override
public void handleRelaunchActivity(ActivityClientRecord tmp,
PendingTransactionActions pendingActions) {
...代码省略...
//注释1,调用handleRelaunchActivityInner方法
handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
...代码省略...
}
private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
PendingTransactionActions pendingActions, boolean startsNotResumed,
Configuration overrideConfig, String reason) {
// Preserve last used intent, it may be set from Activity#setIntent().
final Intent customIntent = r.activity.mIntent;
// Need to ensure state is saved.
if (!r.paused) {
performPauseActivity(r, false, reason, null /* pendingActions */);
}
if (!r.stopped) {
callActivityOnStop(r, true /* saveState */, reason);
}
//注释2,调用handleDestroyActivity
handleDestroyActivity(r, false, configChanges, true, reason);
r.activity = null;
r.window = null;
r.hideForNow = false;
r.nextIdle = null;
// Merge any pending results and pending intents; don't just replace them
if (pendingResults != null) {
if (r.pendingResults == null) {
r.pendingResults = pendingResults;
} else {
r.pendingResults.addAll(pendingResults);
}
}
if (pendingIntents != null) {
if (r.pendingIntents == null) {
r.pendingIntents = pendingIntents;
} else {
r.pendingIntents.addAll(pendingIntents);
}
}
r.startsNotResumed = startsNotResumed;
r.overrideConfig = overrideConfig;
//注释3,调用handleLaunchActivity方法
handleLaunchActivity(r, pendingActions, customIntent);
}
@Override
public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
...代码省略...
WindowManager wm = r.activity.getWindowManager();
View v = r.activity.mDecor;
...代码省略...
//将当前activity对应的viwe从WMS中移除
wm.removeViewImmediate(v);
...代码省略...
}
}
}
注释1处继续调用handleRelaunchActivityInner方法;
注释2处调用handleDestroyActivity方法将当前Activity对应的视图从WMS中移除。
注释3处调用handleLaunchActivity方法将当前Activity对应的视图重新添加到WMS中。
3.2 回调Activity的onConfigurationChanged方法
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
public void handleActivityConfigurationChanged(ActivityClientRecord r,
@NonNull Configuration overrideConfig, int displayId) {
...代码省略...
r.overrideConfig = overrideConfig;
final ViewRootImpl viewRoot = r.activity.mDecor != null
? r.activity.mDecor.getViewRootImpl() : null;
//注释1,调用performConfigurationChangedForActivity方法
final Configuration reportedConfig = performConfigurationChangedForActivity(r,
mConfigurationController.getCompatConfiguration(),
movedToDifferentDisplay ? displayId : r.activity.getDisplayId());
if (viewRoot != null) {
if (movedToDifferentDisplay) {
viewRoot.onMovedToDisplay(displayId, reportedConfig);
}
viewRoot.updateConfiguration(displayId);
}
mSomeActivitiesChanged = true;
}
private Configuration performConfigurationChangedForActivity(ActivityClientRecord r,
Configuration newBaseConfig, int displayId) {
r.tmpConfig.setTo(newBaseConfig);
if (r.overrideConfig != null) {
r.tmpConfig.updateFrom(r.overrideConfig);
}
//注释2,调用performActivityConfigurationChanged方法
final Configuration reportedConfig = performActivityConfigurationChanged(r.activity,
r.tmpConfig, r.overrideConfig, displayId);
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
return reportedConfig;
}
private Configuration performActivityConfigurationChanged(Activity activity,
Configuration newConfig, Configuration amOverrideConfig, int displayId) {
...代码省略...
//调用activity的onConfigurationChanged方法
activity.onConfigurationChanged(configToReport);
...代码省略...
}
}
注释1处继续调用performConfigurationChangedForActivity方法;
注释2处调用performActivityConfigurationChanged方法;
注释3处调用Activity的onConfigurationChanged方法。
参考文章:Android 13 深色主题切换流程