关于activity的状态保存,以前从来没想过还会有这个问题。这里小小总结一下,以备日后查看。
系统默认实现了哪些
1》可以做个测试,我们可以写个demo,界面上有一个EditText。然后你在里面随便填入一些数据。然后按home键回到桌面,这个时候会调用activity的onPause->onStop,然后我们长按home键选择刚才的demo重新打开发现EditText里面的数据并没有丢失。这是因为执行onStop后此activity并没有并销毁,所以它的各种状态也会被保持。
2》我们接着测试,我们在EditText中填入数据,接着旋转屏幕这个时候会重启activity(系统会先回调onDestory,然后立即回调onCreate)。下面就要分两种情况了:a.如果我们为此EditText在布局文件中设置的有id,这种情况我们会看到此EditText中的数据会被保持 b.若我们没有为此EditText设置id的话,我们会看到旋转屏幕后此EditText里面的内容为空(丢失了)。
那么为什么为EditText中设置了id的话它的数据会被保存呢?
Activity中有一个回调方法:protected void onSaveInstanceState(Bundle outState),此方法会默认保存activiy中所有有id的view的信息。比如CheckBox的是否选中的状态等等。保存下来的这些信息会在Activity的另一个回调方法 protected void onRestoreInstanceState(Bundle savedInstanceState) 中恢复.
总结:
通过以上的测试可以得出这样的结论:1>只要activity没有被销毁(系统没有回调onDestory),那么它的各种状态就不会丢失。2>若activity由于某种原因(比如旋转屏幕、系统内存紧张)被销毁,则它里面的有id的view的状态将被保存下来。
以上是系统默认实现好的。
需要我们自己实现的
有时候有些信息要我们自己实现保存,防止activity被销毁后信息丢失。比如游戏的进度。假设这样一个场景:我们正在完游戏,然后来了一电话,则游戏将进入后台,又由于手机配置较低或其它的原因,系统杀死了游戏进程。当我们接完电话后,重新回到游戏会发现游戏进度丢失。为了防止这种情况发生,我们应该这样做:
复写Activity的onSaveInstanceState(Bundle outState)及onRestoreInstanceState(Bundle savedInstanceState)方法,将要保存的信息通过onSaveInstanceState方法的Bundle(关于Bundle这里不多做解释)参数保存。然后在onRestoreInstanceState方法中通过它的Bundle参数savedInstanceState进行恢复即可。完整流程请看下图:
通过测试可知:onSaveInstanceState一般会在onPause后被回调,onRestoreInstanceState一般会在onResume前被回调
实例
写个小例子:如上图,其中我们为EditText及button设置的有id而没有为checkBox设置id.在button上,每点击一次增加一次点击次数,我们通过一个全局变量保存点击次数,然后再通过onSaveInstanceState方法的Bundle保存下来,当重新回到Activity时此Bundle会被传给onRestoreInstanceState然后我们在此方法中恢复即可。布局文件如下:

1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".ActivityLifeDemo" > 7 8 <EditText 9 android:id="@+id/finish" 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" /> 12 13 <CheckBox 14 android:layout_width="fill_parent" 15 android:layout_height="wrap_content" 16 android:text="checkBox" /> 17 18 <Button 19 android:id="@+id/clickTimes" 20 android:layout_width="fill_parent" 21 android:layout_height="wrap_content" 22 android:text="你点击了0次" /> 23 24 </LinearLayout>
Activity代码:

1 public class ActivityLifeDemo extends Activity { 2 3 private static final String TAG = "ActivityLifeDemo"; 4 5 private int click_time = 0; 6 Button btn; 7 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 Log.d(TAG, "onCreate"); 12 setContentView(R.layout.activity_activity_life_demo); 13 btn = (Button) findViewById(R.id.clickTimes); 14 15 btn.setOnClickListener(new OnClickListener() { 16 17 @Override 18 public void onClick(View v) { 19 btn.setText("你点击了" + ++click_time + "次"); 20 } 21 }); 22 23 } 24 25 @Override 26 protected void onRestoreInstanceState(Bundle savedInstanceState) { 27 super.onRestoreInstanceState(savedInstanceState); 28 Log.e(TAG, "onRestoreInstanceState"); 29 click_time = savedInstanceState.getInt("clickTimes"); 30 btn.setText("你点击了" + click_time + "次"); 31 } 32 33 @Override 34 protected void onSaveInstanceState(Bundle outState) { 35 super.onSaveInstanceState(outState); 36 Log.e(TAG, "onSaveInstanceState"); 37 outState.putInt("clickTimes", click_time); 38 } 39 40 @Override 41 protected void onStart() { 42 super.onStart(); 43 Log.d(TAG, "onStart"); 44 } 45 46 @Override 47 protected void onRestart() { 48 Log.d(TAG, "onRestart"); 49 super.onRestart(); 50 } 51 52 @Override 53 protected void onResume() { 54 Log.d(TAG, "onResume"); 55 super.onResume(); 56 } 57 58 @Override 59 protected void onPause() { 60 Log.d(TAG, "onPause"); 61 super.onPause(); 62 } 63 64 @Override 65 protected void onStop() { 66 Log.d(TAG, "onStop"); 67 super.onStop(); 68 } 69 70 @Override 71 protected void onDestroy() { 72 Log.d(TAG, "onDestroy"); 73 super.onDestroy(); 74 } 75 76 }
如何测试:
在EditText中随便输入一些数据,然后选中Checkbox,再点击几次button。然后旋转屏幕。观察哪些数据丢失哪些数据没变。
结论:会看到Checkbox的信息会丢失,这是因为我们没有为它设置id,EditText的数据不变,button中的点击次数也被保存下来了
需要注意的地方:
1》恢复操作也可以在onCreate(它也有一个Bundle参数)中进行,不过还是建议大家在onRestoreInstanceState中进行,这样各个方法的职责更单一
2》onSaveInstanceState不保证一定会被调用,比如我们点击back键主动关闭activity则系统不会回调onSaveInstanceState方法,此时系统理解我们主动关闭所以不需要保存其状态。因此,对于一些需要持久保存的信息,比如保存到数据库中的不应该写在此方法中写,一般会在onPause中做这些。
3》当我们覆写onSaveInstanceState及onRestoreInstanceState时不应该删除父类的默认实现,否则就不能实现保存‘有id的view’的信息了