1 不同情况下activity的生命周期
为了方便描述,我们将activity的销毁分为正常销毁和非正常销毁:
- 正常销毁:被销毁之后不会被自动重建。比如我们主动调用了finish()、杀死了进程、用户通过点击返回键退出了activity等。
- 非正常销毁:被销毁之后会被自动重建。比如,当系统内存紧张时,不可见的activity可能被销毁以节省内存,当activity被重新展现时就会被自动重建。当手机屏幕旋转时,activity(如果没有锁定方向的话)也会被销毁并自动重建。
启动 -> 正常销毁
onCreate
onStart
onResume
onPause
onStop
onDestroy
非正常销毁 -> 自动重建
onPause
onSaveInstanceState*
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState*
onResume
注意这里的onSaveInstanceState和onRestoreInstanceState都是指单参数的方法。在api21之后sdk还提供了它们的双参数版本,它们的作用是允许我们在关机重启时保存和恢复数据。注意区分。
1 息屏 -> 亮屏
2 按home键返回桌面 -> 回到app
3 从activity1跳转到activity2 -> 返回activity1
onPause
onSaveInstanceState*
onStop
onStart
onResume
可见,执行了onSaveInstanceState,但未执行onRestoreInstanceState。
总结一下:
- 当activity被非正常销毁 或 有可能被非正常销毁时,都会调用onSaveInstanceState;
- 只有activity被自动重建时才会调用onRestoreInstanceState。
2 activity非正常销毁时的数据保存与恢复
onSaveInstanceState(Bundle bundle)
和onRestoreInstanceState(Bundle bundle)
的调用时机上面已经说过。利用这两个方法,我们可以在activity被非正常销毁和自动重建时保存和恢复数据,具体来说就是:
- 当activity被非正常销毁或可能被非正常销毁时,会调用
onSaveInstanceState(Bundle bundle)
,我们可以在此方法中将数据保存在参数bundle中。 - 当activity被自动重建时会调用
onRestoreInstanceState(Bundle bundle)
,这里的参数bundle其实就是onSaveInstanceState(Bundle bundle)
的参数bundle,从中可以获取到我们之前保存的数据。
onSaveInstanceState(Bundle bundle)
和onRestoreInstanceState(Bundle bundle)
的默认实现会保存并恢复诸如EditText中的文本、ListView中的滚动条位置等信息。如果想要保存和恢复更多的信息,如成员变量的值,就需要我们自己去onSaveInstanceState(Bundle bundle)
和onRestoreInstanceState(Bundle bundle)
中实现了。
此外,onSaveInstanceState(Bundle bundle)
中保存数据的bundle也会被传递给onCreate(Bundle bundle)
。区别是,在onRestoreInstanceState(Bundle bundle)
中的bundle不可能为null,而onCreate(Bundle bundle)
中的bundle可能为null(当activity不是“非正常销毁并自动重建”时,即当activity正常启动时,此bundle就是null)。建议使用onRestoreInstanceState(Bundle bundle)
来恢复数据。
3 activity非正常销毁时的Intent
在启动一个activity时,经常会通过intent传递一些数据过去:
//MainActivity.java
Intent intent = new Intent(this, Main2Activity.class);
intent.putExtra("name", "zhangSan");
startActivity(intent);
//Main2Activity.java
Log.e("Log", getIntent().getStringExtra("name"));
经测试,当Main2Activity被非正常销毁并自动重建后,由MainActivity传递过来的Intent依然是存在的,也就是说在重建后的Main2Activity中仍然可以通过getIntent().getStringExtra(“name”)获取到数据。