Framework层Config Change流程

更新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
在这里插入图片描述

  1. 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);
      }
   ......
  }
  1. 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进程:
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值