首先,我们来看一下Activity的生命周期。Google官方文档上有较详细的图示。
我们通常通过Back键和Home键来返回上一个窗口或桌面,然后再一次返回当前应用,由此会造成数据的损坏。那么我们再来看一下这两种情况下Activity活动周期的变化。
Back:OnPause()—>OnStop()—->OnDestroy()—–>OnCreate()——>OnStart()—–>OnResume()
Home: Onpause()—>OnStop()—->OnRestart()——>OnStart()—–>OnResume()
通过按Home键回到桌面的情况下,我们可以使用onSaveInstanceState()方法来保存数据,具体用法如下所示:
public class MainActivity extends Activity{
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
...
if(savedInstanceState != null){
String tempData = savedInstanceState.getString("data_key")
this.updateQuestions();
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(savedInstanceState);
Log.d(TAG, "onsaveInstanceState");
String tempData = "something you just typed";
savedInstanceState.putString("data_key", tempData);
}
}
(1)onSaveInstanceState()方法被调用的时候 : Activity 容易被销毁的时候调用, 注意是容易被销毁, 也可能没有销毁就调用了;
– 按下Home键 : Activity 进入了后台, 此时会调用该方法;
– 按下电源键 : 屏幕关闭, Activity 进入后台;
– 启动其它 Activity : Activity 被压入了任务栈的栈底;
– 横竖屏切换 : 会销毁当前 Activity 并重新创建;
屏幕旋转的生命周期如图:
onPause()——>onSaveInstanceState()——>onPause()——>onStop()
——>onDestroy()——>onCreate()——>判断savedInstanceon()是否为空
——>Start()——>onResume()
(2)onSaveInstanceState()方法不会被调用的时候:
– 用户主动销毁不会调用 : 当用户点击回退键 或者 调用了 finish() 方法, 不会调用该方法;
– 调用时机不固定 : 该方法一定是在 onStop() 方法之前调用, 但是不确定是在 onPause() 方法之前 还是 之后调用;
– 布局中组件状态存储 : 每个组件都 实现了 onSaveInstance() 方法, 在调用函数的时候, 会自动保存组件的状态, 注意, 只有有 id 的组件才会保存;
– 关于默认的 super.onSaveInstanceState(outState) : 该默认的方法是实现 组件状态保存的;
通过按Back键回到桌面的情况下,我们可以使用moveTaskToBack来保存数据,具体用法如下所示:
public class MainActivity extends Activity {
//...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//...
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
moveTaskToBack(true);
}
}