Android Activity savedInstanceState
2017-06-01 11:14
260 查看
最近了解了一些关于Android的savedInstanceState相关的知识,在此进行一下总结。
在Android的Activity控件中的onCreate方法中,我们可以获得的一个参数为savedInstanceState:
该参数的作用是什么呢?
这时,我们就得提到构造savedInstanceState的另一个方法:
该方法的作用为:
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切换屏幕方向恢复数据的例子:
Activity的布局xml文件包含了一个TextView与一个EditText。
首次运行:
在EditText中输入内容:
进行屏幕切换:
不调用onRestoreInstanceState的父类方法,其余步骤同上,屏幕切换后:
可以看到,在没有调用父类方法时,EditText的输入内容变回了原本的Name而非我们输入的input something,由此看来,savedInstanceState确实具有保存Activity中布局的UI状态的功能。
因此,在我们实现自定义View控件的时候也应该记得实现View的onSaveInstanceState方法,用于存储UI控件的状态(默认实现为什么都不保存)。
PS:savedInstance虽然默认会保留fragment相关信息,但只是保留了fragment 对象本身而已(不需要我们再次add fragment),但每次初始化图像时均会重新调用onCreateView重新绘制,因此UI上的状态也会丢失(比如EditText输入的内容等),此时我们需要重写fragment的onSaveInstanceState自行保存其中的UI状态,并在onViewStateRestored方法中恢复:
在Android的Activity控件中的onCreate方法中,我们可以获得的一个参数为savedInstanceState:
@Override protected void onCreate(Bundle savedInstanceState)
该参数的作用是什么呢?
这时,我们就得提到构造savedInstanceState的另一个方法:
@Override protected void onSaveInstanceState(Bundle outState)
该方法的作用为:
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切换屏幕方向恢复数据的例子:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MyLog"; private TextView textView; private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { // 初次运行 textView = (TextView) findViewById(R.id.text_view); editText = (EditText) findViewById(R.id.editText); textView.setText("before"); } else { // 恢复数据 textView = (TextView) findViewById(R.id.text_view); textView.setText("after"); } } @Override protected void onSaveInstanceState(Bundle outState) { // 保存各种View的状态 super.onSaveInstanceState(outState); Log.d(TAG, "onSaveInstanceState"); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { // 恢复各种View的状态 super.onRestoreInstanceState(savedInstanceState); Log.d(TAG, "onRestoreInstanceState"); } }
Activity的布局xml文件包含了一个TextView与一个EditText。
首次运行:
在EditText中输入内容:
进行屏幕切换:
不调用onRestoreInstanceState的父类方法,其余步骤同上,屏幕切换后:
@Override protected void onRestoreInstanceState(Bundle savedInstanceState) { // 恢复各种View的状态 // super.onRestoreInstanceState(savedInstanceState); Log.d(TAG, "onRestoreInstanceState"); }
可以看到,在没有调用父类方法时,EditText的输入内容变回了原本的Name而非我们输入的input something,由此看来,savedInstanceState确实具有保存Activity中布局的UI状态的功能。
因此,在我们实现自定义View控件的时候也应该记得实现View的onSaveInstanceState方法,用于存储UI控件的状态(默认实现为什么都不保存)。
PS:savedInstance虽然默认会保留fragment相关信息,但只是保留了fragment 对象本身而已(不需要我们再次add fragment),但每次初始化图像时均会重新调用onCreateView重新绘制,因此UI上的状态也会丢失(比如EditText输入的内容等),此时我们需要重写fragment的onSaveInstanceState自行保存其中的UI状态,并在onViewStateRestored方法中恢复:
public class MyFragment extends Fragment { private static final String VIEWS_TAG = "my_fragment:views"; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_my, container, false); } @Override public void onViewStateRestored(Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); // 恢复UI状态 if (savedInstanceState != null && getView() != null) { SparseArray<Parcelable> sparseArray = savedInstanceState.getSparseParcelableArray(VIEWS_TAG); getView().restoreHierarchyState(sparseArray); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存UI状态 SparseArray<Parcelable> sparseArray = new SparseArray<Parcelable>(); if (getView() != null) { getView().saveHierarchyState(sparseArray); outState.putSparseParcelableArray(VIEWS_TAG, sparseArray); } } }
相关文章推荐
- <Android>在Activity被非正常杀死并重建时,使用savedInstanceState进行数据恢复的简单实例
- Android--->activity高级运用,保存前一个界面为完成的数据savedInstanceState。
- Android BaseSavedState 以及 Activity onSaveInstanceState 和 onRestoreInstanceState 方法使用注意事项
- onCreate(Bundle savedInstanceState) 说明 setContentView(R.layout.activity_main); 需要放到操作或设置控件的前面
- Activity的onCreate()的参数savedInstanceState
- Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法
- Android翻译】关于Activity的onSaveInstanceState调用时机的说明
- 【Android翻译】关于Activity的onSaveInstanceState调用时机的说明
- Android开发之InstanceState详解(转)---利用其保存Activity状态
- Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法
- android onCreate(Bundle savedInstanceState)
- 【Android 应用开发】Activity 状态保存 OnSaveInstanceState参数解析
- Android savedInstanceState的作用和用法
- Android savedInstanceState的使用
- Activity中的onCreate(Bundle savedInstanceState)
- Android.Bundle savedInstanceState 的意义用法
- 关于Android应用程序中重载函数onCreate(Bundle savedInstanceState)的一些简单说明
- 【Android翻译】关于Activity的onSaveInstanceState调用时机的说明
- Android中的savedInstanceState
- android onCreate(Bundle savedInstanceState)