android横竖屏切换的生命周期
没设置configChanges,销毁后重建:
onCreate--onStart--onResume--onPause--onStop--onSaveInstanceState--onDestroy--onCreate--onStart--onRestoreInstanceState--onResume--onPause--onStop--onDestroy
设置configChanges:
横竖屏切换走onConfigurationChanged方法,不会重新走生命周期
android:configChanges="keyboardHidden|screenSize|orientation"
源码:
//config变化,分发到应用上,先去ensure topActivity确定该走Activity
//的relaunch还是onConfigurationChanged,再去ensure其他Activities
mAtmService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
开始relaunch:
ActivityThread.handleRelaunchActivityInner(args..){
if (!r.paused) {
performPauseActivity(r, false, reason, null /* pendingActions */);
}
if (!r.stopped) {
callActivityOnStop(r, true /* saveState */, reason);
}
handleDestroyActivity(r, false, configChanges, true, reason);
...
handleLaunchActivity(r, pendingActions, customIntent);
}
Framework层Config Change流程_configchange流程-CSDN博客
Framework层Config Change流程_configchange流程-CSDN博客
当由系统发起而非人为手动关闭Activity的时候,Activity有可能在未来的某个时机恢复重建。Android系统提供了两套机制,用以保存和恢复界面状态。 这两套机制我个人分别给其取名为 Save-Restore InstanceState机制和RetainNonConfiguration机制
1)Save-Restore InstanceState机制的初衷是保存界面的一些瞬时状态,常保存一些比较轻量级的数据,因为保存过程需要经历数据的序列化和反序列化。onSaveInstanceState(outState)的被调用的条件:非手动杀死Activity而是系统kill同时可能会在未来重建时。
2)RetainNonConfigurationInstance机制:当如横竖屏的切换、语言切换等配置发生改变时也会触发Activity的重建。这种由配置发生改变而导致的Activity重建除了会触发Save-Restore InstanceState机制之外也会触发RetainNonConfigurationInstance机制。用于保存配置发生前的数据,这个数据理论上是没有结构和大小限制的甚至可以把旧Activity本身保存其中。
如果两个方法同时出现时,onSaveInstanceState()方法执行在先,而onRetainNonConfigurationInstance()方法执行在后。它们的执行顺序都在onStop()和onDestroy()之间
viewmodel
- 重写了onRetainNonConfigurationInstance()方法并把方法设置为了final。onRetainNonConfigurationInstance()方法内部创建NonConfigurationInstances对象nci,把viewModelStore存放到nci,同时收集onRetainCustomNonConfigurationInstance()方法的返回值存在nci里
- viewmodel中横竖屏转换,横竖屏切换等配置发生变化导致的重建时,新Activity中可听过ensureViewModelStore()方法获取从旧Activity传递过来viewmodelstore,这样就实现了横竖屏切换的时候viewmodel不丢失。
- 另外值得注意的点是,Activity onDestory的时候,会通过isChangingConfigurations()方法判断activity是否处于配置变化状态,如果不是就会将viewmodelstores清空掉。
ActivityThread.java
销毁时存
void handleDestroyActivity(args..){
...
r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
...
}
//handleLaunchActivity()--performLaunchActivity(),重新创建时取
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
...
return activity;
}
ensureViewModelStore():恢复viewmodel数据
activity destory时且不是因为配置项改变导致,clear viewmodel
总结
1.设置configChanges,会触发onConfigurationChanged方法,不会重新走生命周期,也就不会走数据回复机制(Save-Restore InstanceState机制和RetainNonConfiguration机制)
2.没有设置configChanges,当由系统发起而非人为手动关闭Activity的时候,会触发Save-Restore InstanceState机制,当由配置发生改变而导致的Activity重建还会额外触发RetainNonConfiguration机制
3.如果两个方法同时出现时,onSaveInstanceState()方法执行在先,而onRetainNonConfigurationInstance()方法执行在后。它们的执行顺序都在onStop()和onDestroy()之间
4.Save-Restore InstanceState机制的初衷是保存界面的一些瞬时状态,常保存一些比较轻量级的数据,因为保存过程需要经历数据的序列化和反序列化;RetainNonConfigurationInstance机制用于保存配置发生前的数据,这个数据理论上是没有结构和大小限制
4.Activity onDestory的时候,会通过isChangingConfigurations()方法判断activity是否处于配置变化状态,如果不是就会将viewmodelstores清空掉。
5.在activityrelaunch过程中,销毁时调用onRetainNonConfigurationInstance保存了viewModelStore,create时在取读取该viewModelStore,完成了配置改变后viewmodel的数据保存。