onConfigurationChanged与 Save-Restore InstanceState机制与RetainNonConfiguration机制

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的数据保存。

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值