最近了解了一些关于Android的savedInstanceState相关的知识,在此进行一下总结。
在Android的Activity控件中的onCreate方法中,我们可以获得的一个参数为savedInstanceState:
1 |
|
该参数的作用是什么呢?
这时,我们就得提到构造savedInstanceState的另一个方法:
1 |
|
该方法的作用为:
Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(Bundle) or onRestoreInstanceState(Bundle) (the Bundle populated by this method will be passed to both).
即:用于保存Activity被杀死前一刻的每个实例的状态,然后当Activity被重启时,传递给onCreate与onRestoreInstanceState方法
该方法的调用时间为:
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state.
即:当一个Activity可能被杀死时调用。由于是在Activity可能被杀死时调用,但许多情况下调用了onSaveInstanceState方法后Activity并不一定会被杀死,因此其与调用onCreate与onRestoreInstanceState并不是成对的。常见的调用时间有:
- 当用户按下HOME键时
- 长按HOME键,选择运行其他的程序时
- 按下电源按键(关闭屏幕显示)时
- 从activity A中启动一个新的activity时
- 屏幕方向切换时
另外,该方法与Activity的生命周期没有关系,并不会依照特定的顺序被调用。但如果被调用时,一定保证会在onStop方法前被调用。
值得注意的是:
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.
据博主所了解,onSaveInstanceState默认方法会为我们自动存储当前Activity对应布局中的View以及Fragment相关的状态,如果需要存储某些变量的值则需要我们重写onSaveInstanceState方法自行操作,重写方法时应注意调用父类方法来保存Activitiy中的UI 状态,通过onRestoreInstanceState方法恢复数据同理。
下面为一个Activity切换屏幕方向恢复数据的例子:
1 | public class MainActivity extends AppCompatActivity { |
Activity的布局xml文件包含了一个TextView与一个EditText。
首次运行:
在EditText中输入内容:
进行屏幕切换:
不调用onRestoreInstanceState的父类方法,其余步骤同上,屏幕切换后:
1 |
|
可以看到,在没有调用父类方法时,EditText的输入内容变回了原本的Name而非我们输入的input something,由此看来,savedInstanceState确实具有保存Activity中布局的UI状态的功能。
因此,在我们实现自定义View控件的时候也应该记得实现View的onSaveInstanceState方法,用于存储UI控件的状态(默认实现为什么都不保存)。
PS:savedInstance虽然默认会保留fragment相关信息,但只是保留了fragment 对象本身而已(不需要我们再次add fragment),但每次初始化图像时均会重新调用onCreateView重新绘制,因此UI上的状态也会丢失(比如EditText输入的内容等),此时我们需要重写fragment的onSaveInstanceState自行保存其中的UI状态,并在onViewStateRestored方法中恢复:
1 | public class MyFragment extends Fragment { |