Activity/View状态保存和恢复 onSaveInstanceState()和onRestoreInstanceState()

Activity/View onSaveInstanceState和onRestoreInstanceState触发的时机/必要条件

1:先看Application Fundamentals上的一段话:

  Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key)

 从这句话可以知道,当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。

注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个activity(假定为activity A)显示在当前task的最上层时,其onSaveInstanceState方法会在什么时候被执行,有这么几种情况:


1、当用户按下HOME键时。

这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
2、长按HOME键,选择运行其他的程序时。
3、按下电源按键(关闭屏幕显示)时。
4、从activity A中启动一个新的activity时。
5、屏幕方向切换时,例如从竖屏切换到横屏时。

在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统又会自动地创建activity A,所以onSaveInstanceState一定会被执行

总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。
至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行


另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原.

 

2:view自己也有相应的onSaveInstanceState和onRestoreInstanceState,它的出发时机于此不同。

    The default implementation takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState(Bundle)). If you override this method to save additional information not captured by each individual view, you will likely want to call through to the default implementation, otherwise be prepared to save all of the state of each view yourself. If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().

    默认的实现负责了大部分UI实例状态(的保存),采用的方式是调用UI层上每个拥有id的view的onSaveInstanceState() ,并且保存当前获得焦点的view的id(所有保存的状态信息都会在默认的onRestoreInstanceState(Bundle)实现中恢复)(焦点也是可能会被保存的)。如果你覆写这个方法来保存额外的没有被各个view保存的信息,你可能想要在默认实现过程中调用或者自己保存每个视图的所有状态。如果被调用,这个方法会在onStop()前被触发,但系统并不保证是否在onPause()之前或者之后触发。

有如下两个必要条件:

1.设定有指定的id:   

android:id="@+id/gallary"

2.设定saveEnabled:
       android:saveEnabled="true"

 

参考文档:

1:http://www.cnblogs.com/heiguy/archive/2010/10/30/1865239.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 `Activity` 的 `onSaveInstanceState` 方法中保存 `ViewPager2` 的状态,可以重写该方法,并在其中保存 `ViewPager2` 的当前选中项索引。示例代码如下: ```java public class MainActivity extends AppCompatActivity { private ViewPager2 viewPager2; private int currentItem; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager2 = findViewById(R.id.viewPager2); // 设置 ViewPager2 的 Adapter 和数据 // ... if (savedInstanceState != null) { // 从保存的 Bundle 中恢复 ViewPager2 的当前选中项 currentItem = savedInstanceState.getInt("currentItem", 0); viewPager2.setCurrentItem(currentItem, false); } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // 保存 ViewPager2 的当前选中项 currentItem = viewPager2.getCurrentItem(); outState.putInt("currentItem", currentItem); } } ``` 在 `Activity` 的 `onCreate` 方法中恢复 `ViewPager2` 中 `Fragment` 的状态,可以在创建 `FragmentStateAdapter` 时传入 `FragmentManager` 和 `Lifecycle` 对象,然后在 `onCreate` 方法中使用该适配器创建 `ViewPager2`,并设置其 Adapter。示例代码如下: ```java public class MainActivity extends AppCompatActivity { private ViewPager2 viewPager2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager2 = findViewById(R.id.viewPager2); // 创建 FragmentStateAdapter FragmentStateAdapter adapter = new MyFragmentStateAdapter(getSupportFragmentManager(), getLifecycle()); // 设置 ViewPager2 的 Adapter viewPager2.setAdapter(adapter); } } ``` 其中 `MyFragmentStateAdapter` 是继承自 `FragmentStateAdapter` 的一个自定义适配器,示例代码如下: ```java public class MyFragmentStateAdapter extends FragmentStateAdapter { private static final int NUM_PAGES = 3; public MyFragmentStateAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) { super(fragmentManager, lifecycle); } @NonNull @Override public Fragment createFragment(int position) { // 根据 position 创建对应的 Fragment return MyFragment.newInstance(position); } @Override public int getItemCount() { return NUM_PAGES; } } ``` 在 `MyFragment` 中可以保存恢复 Fragment 的状态,具体的实现方法可以参考前面我的回答。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值