Activities
生命周期
本质上来说,activity A有三种状态:
- Resumed:A在最前面并且拥有用户焦点,这种状态一般也称为running
- Paused:activity B在最前面并且拥有用户焦点,但是A仍然可见,也就是说B要么是透明的,要么没有把后面的A完全覆盖。此状态的activity对象仍在内存,维持着所有状态和成员信息,并且仍附着window manager,有可能被系统销毁。
- Stopped:A被B完全覆盖,此状态的activity对象仍在内存,维持着所有状态和成员信息,但已经不附着window manager,不可见并随时有可能被系统销毁。
public class ExampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // The activity is being created. } @Override protected void onStart() { super.onStart(); // The activity is about to become visible. } @Override protected void onResume() { super.onResume(); // The activity has become visible (it is now "resumed"). } @Override protected void onPause() { super.onPause(); // Another activity is taking focus (this activity is about to be "paused"). } @Override protected void onStop() { super.onStop(); // The activity is no longer visible (it is now "stopped") } @Override protected void onDestroy() { super.onDestroy(); // The activity is about to be destroyed. } }
Note:如上生命周期回调函数的覆写,请先调用父类默认的实现函数。
完整的生命周期:onCreate —> onDestroy
可见的生命周期:onStart —> onStop
前台的生命周期:onResume—>onPause
onPause、onStop、onDestroy三种方法之后,都有可能被系统销毁(低内存),由于onPause首当其冲,所以你必须使用onPause来保存用户的持久性重要数据,而且挑选最重要的来保存,因为onPause执行频繁,逻辑耗时太长会影响用户体验。
Note:极端场景下,其他状态下也有可能被销毁。
保存activity状态
activity被系统意外销毁之前会调用onSaveInstanceState,通过Bundle(putString、putInt来保存键值对数据)传递数据,如果activity被销毁后,重启activity时,系统会将这个保存的Bundle数据传递给onCreate和onRestoreInstatnceState,通过这两个方法,你可以恢复Bundle中保存的状态数据。(首次启动时,Bundle数据为null)
Note:无法保证onSaveInstanceState一定会在activity被销毁前执行,比如用户按返回键时并不会触发onSaveInstanceState,所以比较好的做法是临时性地状态可以用onSaveInstanceState保存,而数据需要持久化保存的使用onPause。
默认的,系统自带的widget都实现了onSaveInstanceState,比如EditText默认保存用户的输入数据,你需要做的就是为每个widget通过android:id指定唯一的ID。当然你可以通过android:saveEnabled=false或者调用setSaveEnabled来强制关闭系统的这种默认行为。
如果我们需要覆写onSaveInstanceState()方法, 一般会在第一行代码中调用该方法的默认实现:super.onSaveInstanceState()。
对于数据是否保存比较简单的验证方法就是横竖屏,看一下你的app中用户输入的数据是否还有所保留。(当然有可能开发者强制横竖屏不重新销毁创建activity)
配置变化
某些设备配置发生变化时,系统为了重新加载新配置的资源,activity会被销毁重新创建,比如横竖屏、语言变化等。
应对这种变化,可以通过onSaveInstanceState()
和onRestoreInstanceState()
(或者 onCreate()
)来保存状态。
协同
A启动B:
- A 执行onPause
- B顺序执行onCreate、onStart、onResume
- 如果A不可见了,执行onStop
如果A需要保存数据供B使用,那么逻辑应该是放在onPause之前,而不是在onStop之前。