Android saveInstanceState

以前一直对onCreate(Bundle saveInstanceState)的参数不知其意,今天特地研究了一下,记录于此。

与此相关的有两个method:

 @Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save away the original text, so we still have it if the activity
    // needs to be killed while paused.
    savedInstanceState.putInt("IntTest", 0);
    savedInstanceState.putString("StrTest", "savedInstanceState test");
    super.onSaveInstanceState(savedInstanceState);
    Log.e(TAG, "使用了我的onSaveInstanceState");
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    int IntTest = savedInstanceState.getInt("IntTest");
    String StrTest = savedInstanceState.getString("StrTest");
    Log.e(TAG, "onRestoreInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
}

需要注意的是,这两个method都是非生命周期method(区别于onCreate等)。这两个method只有在由android framework kill一个Activity(内存不足,用户直接按home键等等)才会触发,你可以在此存储一些数据,这样就可能在用户下次进入时恢复到之前的状态。而当用户正常退出一个Activity时(例如:按下back键)则不会触发这两个method。

既然这两个method你不一定会被触发,那么我们来测试一下,它们在什么情况下会被触发呢?

首先是onSaveInstanceState(Bundle savedInstanceState):

按照文档解释实说当activity容易被销毁时会触发该method,也就是该activity处于栈顶的时候。

我目前只意识到了以下几种情况会触发,如果大家有什么发现,欢迎交流补充,谢谢:
1.进入Activity后按下home键;
2.进入Activity后按下电源键;
3.在当前Activity下选择进入其他app,这个实现不太一样,了如我的MX3时上拉进入其它app,有的android机器则是长按home键;
4.横竖屏幕切换(Activity会被销毁,并restart);
5.当前Activity失去焦点(被其他Activity覆盖)

截图如下:

Alt text

接下来我们看看onRestoreInstanceState(Bundle savedInstanceState) method,这个方法只有在当前Activity确实被销毁了的情况下才会调用。如果是“有可能被销毁则不会被调用”。
因为这个比较难以观测,所以只给出横竖屏切换时的结果(横竖屏切换时Activity会被destroy并重新onCreate):
请看打印出来的倒数第二行,另外注意:onRestoreInstanceState()在onStart() 和 onPostCreate(Bundle)之间调用。可以自行打印看下。

Alt text

总结:
一般情况下推荐onSaveInstanceState()用于保存一些临时性的状态,一边用户再次返回时保留之前状态,留下很好的用户体验;而数据的持久化存储则应该在onPause() 方法中完成。