趁着最近没什么项目,打算回顾整理下android的基础知识,算是查漏补缺。
关于Activity的生命周期,参看了相关书籍(android开发艺术探索)和文档,还是对以前的知识体系有了很大程度的改善的,在这里记录一下。
1、典型情况下的生命周期
典型情况,指有用户参与的情况下,Activity所经过的生命周期的改变。
首先是经典的生命周期图:
1.1、首先介绍下几种状态:
1)Created:刚刚完成一些初始化操作,Activity未可见。
2)Started:Activity可见,但还在还没出现在前台。
3)Resumed:Activity可见,且在前台。(可视,可接受输入,可执行代码)
4)Paused:(部分可视,不可接受输入,不可执行代码)
5)Stopped:(不可视,不可接受输入,不可执行代码)
其中(“Created”和“Started”)是瞬态,系统会通过调用下一个生命周期回调方法从这些状态快速移到下一个状态。 也就是说,在系统调用 onCreate() 之后,它会快速调用 onStart(),紧接着快速调用 onResume()。
1.2、从回调方法的角度,几种情况下的生命周期:
1)activity第一次启动时,回调如下,对应图上的1:
onCreate()->onStart()->onResume()
2)此时用户打开另外一个新的Activity,或者切换到桌面,或者锁屏时,回调如下,对应图上的2:
onPause()->onStop()
3)这时再次回到原来的activity(重新点击原来Activity的图标,或者通过近期任务,或者解锁屏幕),回调如下对应图上的3:
onRestart()->onStart()->onResume()
4)这时候,如果按back键回退的时候,回调如下,对应图上的4:
onPause()->onStop()->onDestroy()
5)图上的5 是极端情况。用户很难重现这一情景的。
6)当Activity被系统回收后再次打开,生命周期跟情况1一样:
onCreate()->onStart()->onResume()
从整个生命周期来说: onCreate()和onDestory()是配对的,分别标识着activity的创建和销毁,并且只可能一次调用。
从activity是否可见来说: onStart()和onStop是配对的。
从Activity是否位于前台来说: onResume和onPause是配对的。
1.3、从一个activity启动另外一个activity时的情况:
新启动一个Activity时,旧的Activity的onPause方法先执行,再启动新的Activity:
例如从activityA通过startActivity启动activityB,回调如下:
activityA -> onPasuse()
activityB -> onCreate()
activityB -> onStart()
activityB -> onResume()
activityA-> onStop()
直接上一个测试图:
1)我再ActivityA中启动ActivityB,回调如下(每次启动新的Activity时候,都会调用onSaveInstanceState,后面会介绍):
2)然后再按返回键,返回ActivityA,回调如下:
2、异常情况下的生命周期
先来了解两个回调函数:
1)onSaveInstanceState函数
某些情况下,系统会自动调用它来保存Activity的一些数据,但当除它默认要保存的数据外,我们还要保存一些其他数据的时候, 我们就需要覆盖onSaveInstanceState()方法来保存Activity的附加信息。
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("param", param);
Log.i(TAG, "onSaveInstanceState called. put param: " + param);
super.onSaveInstanceState(outState);
}
调用时机:当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。
这里的容易被销毁,指的是可能被系统销毁的时候(强调的是可能),主要有如下几种情况:
1、当用户按下HOME键时。
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,
自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,
让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则。
2、长按HOME键,选择运行其他的程序时。
3、按下电源按键(关闭屏幕显示)时。
4、从activity A中启动一个新的activity时。
5、屏幕方向切换时,例如从竖屏切换到横屏时。
2)onRestoreInstanceState函数
这个方法与onSaveInstanceState方法对应。在onSaveInstanceState中保存数据,那么则在onRestoreInstanceState中恢复数据。
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
param = savedInstanceState.getInt("param");
Log.i(TAG, "onRestoreInstanceState called. get param: " + param);
super.onRestoreInstanceState(savedInstanceState);
}
onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提是,activity“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用。
异常情况主要有下面两种情况:
2.1、情况1:资源相关的系统配置发生改变
资源相关的系统配置发生改变,举个例子:当前Activity处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity就会销毁并且重建。
测试代码:
public class LifeCycleActivity extends AppCompatActivity {
private static final String TAG = "LifeCycleActivityTest";
private Context context = this;
private int param = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate called.");
setContentView(R.layout.activity_life_cycle);
Button btn_test = (Button) findViewById(R.id.btn_test);
btn_test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, TargetActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart called.");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart called.");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume called.");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause called.");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop called.");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestory called.");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("param", param);
Log.i(TAG, "onSaveInstanceState called. put param: " + param);
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
param = savedInstanceState.getInt("param");
Log.i(TAG, "onRestoreInstanceState called. get param: " + param);
super.onRestoreInstanceState(savedInstanceState);
}
}
1)启动Activity:
2)直接按电源键锁屏:
这时候调用了onSaveInstanceState方法。因为存在Activity被销毁的可能。
3)解锁屏幕:
这时候并没有调用onRestoreInstanceState方法,因为Activity并没有被真正销毁重建。
4)然后我将手机屏幕从竖屏切换到横屏:
这时候,onSaveInstanceState方法和onRestoreInstanceState方法都被调用了。因为Activity被系统重建了,而且是不为用户所知的情况下。
而且onSaveInstanceState必定是在onStop方法之前调用(与onPause方法的顺序不确定),onRestoreInstanceState必定是onStart方法后,onResume方法前调用。
2.2、情况2:资源内存不足导致低优先级Activity被杀死
Activity优先级
前台Activity——正在和用户交互的Activity,优先级最高
可见但非前台Activity——Activity中弹出的对话框导致Activity可见但无法交互
后台Activity——已经被暂停的Activity,优先级最低
系统内存不足时,会按照以上优先级杀死Activity,并通过onSaveInstanceState和onRestoreInstanceState这两个方法来存储和恢复数据。
这种情况是无法模拟的。但是函数调用情况跟情况1是一样的。
2.3 不让Activity重新创建的方法
系统配置有很多内容,当某项改变时,如果不想让Activity重新创建可以在AndroidMainfest中给Activity指定configChanges属性。
android:configChanges="xxx"
属性,常用的主要有下面三个选项:
local:设备的本地位置发生了变化,一般指切换了系统语言;
keyboardHidden:键盘的可访问性发生了变化,比如用户调出了键盘;
orientation:屏幕方向发生了变化,比如旋转了手机屏幕。```
配置了android:configChanges="xxx"属性之后,Activity就不会在对应变化发生时重新创建,而是调用Activity的onConfigurationChanged方法。
参考:
>http://blog.csdn.net/wodetiantang007/article/details/8543357
>http://blog.csdn.net/liuhe688/article/details/6733407