type
status
date
slug
summary
tags
category
icon
password

主要方法

  • onSaveInstanceState(Bundle outState)
  • onRestoreInstanceState(Bundle savedInstanceState)

调用时机

  • onSaveInstanceState(Bundle outState)
    • 从Android P开始,该方法如果被调用,也是在onStop之后;
      在Android P之前,则会在onStop之前调用,但是不能保证是在onPause之前还是之后;
  • onRestoreInstanceState(Bundle savedInstanceState)
    • onStart()之后,onPostCreate() 之前执行,并且只有在重新创建Activity的时候才会执行
      不过一般的实现是在onCreate()中拿到保存的bundle进行自定义的恢复逻辑;
      在onRestoreInstanceState()中会默认恢复View层级的状态信息.
onSaveInstanceState()在onStop之后都会执行(AndroidP前后版本可能会有所差异),但是onRestoreInstanceState()则只在某些特定的场景才会执行:
  • 在“开发者选项-不保留活动”中设置,从Activity A跳转到Activity B再返回,也会执行onRestoreInstanceState()
    • 这种情况下,Activity重建时可能会onResume()-onPause()-onResume();
  • App处于后台,被系统回收,导致Activity被销毁,当再次重启Activity的时候;
  • 配置信息变更的时候,比如屏幕方向切换的时候;
在onCreate()中的savedInstanceState有可能为null,而onRestoreInstanceState()中的savedInstanceState()则一定不为null;

保存了什么状态

各种状态都是保存到Bundle中的,如果有比较复杂的结构,就使用Parcelable.
主要存储了以下信息:
  • View层级中View的状态信息
    • 具有ID的View的信息
    • 拥有焦点的View的信息
    • 状态信息存储在不同View中的BaseSavedState中,这个类是一个Parcelable类
  • Fragment信息
  • Dialog信息
不同的View中可以有不同的BaseSavedState实现,用来保存各自的信息,比如在ViewPager2中保存的信息时当前选中的位置.
而且View中也有对应的onSaveInstanceState()方法,用于保存自身的状态信息.

保存在哪了

保存到了磁盘(及手机上的存储器)上(这一点存疑)
notion image

持久化的问题

有一个PersistableBundle可以当作持久化的状态保存.
在onCreate(),onsaveInstanceState(),onRestoreInstanceState()中也有对应的参数传递.
但是目前在应用层很少使用这个类.

源码分析

state bundle的创建

在ActivityThread中有:
private void callActivityOnSaveInstanceState(ActivityClientRecord r) { r.state = new Bundle(); r.state.setAllowFds(false); if (r.isPersistable()) { r.persistentState = new PersistableBundle(); mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); } }

保存了什么状态

在Activity中有:
final void performSaveInstanceState(@NonNull Bundle outState) { dispatchActivityPreSaveInstanceState(outState); // View层级信息 onSaveInstanceState(outState); // Dialog信息 saveManagedDialogs(outState); // Fragment信息 mActivityTransitionState.saveState(outState); // 是否请求过权限 storeHasCurrentPermissionRequest(outState); if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState); dispatchActivityPostSaveInstanceState(outState); } protected void onSaveInstanceState(@NonNull Bundle outState) { // View层级信息,mWindow最终也是通过DecorView去获取的层级信息 outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState()); // 自动填充的内容 outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId); Parcelable p = mFragments.saveAllState(); if (p != null) { outState.putParcelable(FRAGMENTS_TAG, p); } if (mAutoFillResetNeeded) { outState.putBoolean(AUTOFILL_RESET_NEEDED, true); getAutofillManager().onSaveInstanceState(outState); } dispatchActivitySaveInstanceState(outState); }
Android开机动画分析Activity启动流程分析
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏