Activity先导:lifeCycle、通讯、启动模式、源码
一、lifeCycle:Activity生命周期
onCreate() onRestart() onStart() onResume() onPause() onStop() onDestroy()
- onCreate() 表示该Activity正在被创建,可做一些初始化工作,加载布局资源和初始化数据等。
- onRestart() 表示该Activity正在被重启。Activity从不可见重新变为可见状态,onStop调用后又回到该Activity的时候会调用
- onStart() 表示正在被启动这时,该Activity已经处于可见,但是还没有出现在前台,无法和用户交互
- onResume() 表示该Activity已经可见并且已经出现在前台开始进行活动。
- onPause() 表示该Activity正在停止,正常情况下,会紧接着执行onStop,特殊情况下,如果快速回到上一个Activity,Activity又回到前台,则会调用onResume方法。如果,下一个Activity是透明主题的,该Activity也只能进入onPause,不会进入onStop,当再回复到前台时,调用onResume方法。在该生命周期中不能做太多耗时的操作,因为新的Activity需要等这个Activity执行完onPause之后才调用onCreate。(停止动画或者数据存储)
- onStop() 已进入后台进程,表示该Activity已经停止,不可见,可以做一些稍微重量级的回收工作,但不能太耗时。
- onDestroy() 表示Activity即将被销毁,可以做回收工作及最后的资源释放。
典型案例:
- 案例一: A中启动B,B将A完全覆盖的时候,activity的生命周期A: onPause() -> B: onCreate() -> B: onStart() ->B: onResume() -> A: onStop()按下back键,退出B的生命周期B: onPause() -> A: onRestart() -> A: onStart() -> A: onResume() -> B: onStop() -> B: onDestroy()
- 案例二: A中启动B,B是透明主题,A还处于可见状态,activity的生命周期A: onPause() -> B: onCreate() -> B: onStart() ->B: onResume() 按下back键,退出B的生命周期B: onPause() -> A: onResume() -> B: onStop() -> B: onDestroy()
二、Activity 通讯
A -> B
Activity间传输数据,A启动B,同时传输数据,可以使用Intent.putExtra的形式传输的数据类型有基本数据类型、基本数据类型的数组、实现了Serializable、Parcelable的类、Parcelable数组、Bundle、IntegerArrayList、StringArrayList、ParcelableArrayList;B通过getIntent得到一个Intent对象,然后通过对应的get获取对应的数据。
A -> B B -> A
A启动B后,在B结束后,需要传数据给A,A在启动的时候,可以通过startActivityForResult(Intent intent, int requestCode),B中在finish前,通过调用setResult(int resultCode,Intent data)的形式,将需要传输的数据放到Intent中传给A。A通过onActivityResult(int requestCode, int resultCode, Intent data)进行获取数据。
注意的点:
使用startActivityForResult及onActivityResult进行页面传值,在5.0之前的手机,要结合启动模式,如果启动的Activity是singleInstance、被启动的Activity是singleTask或singleInstance,则无法使用原因是:5.0之前,如果设置了以上的启动模式,系统在启动Activity的时候,则会在LaunchFlags中加入FLAG_ACTIVITY_NEW_TASK标志,如果又这个标识,则onActivityResult会立即收到一个cancel的消息5.0 作了修改,无论是启动模式,都可以使用startActivityForResult和onActivityResult进行数据传输。
三、Activity的四种启动模式
standard 标准模式
默认的启动模式,没启动一个Activity都会重新创建一个实例,任务栈中可以存在多个实例,同时,运行的任务栈在启动该Activity的任务栈中。
singleTop 栈顶复用
如果新的Activity已经在栈顶了,则复用栈顶的实例,不会重新创建,同时调用onNewIntent。如果栈中已经存在该实例,但是不在栈顶,则不会复用,会重新创建新的实例。
singleTask 栈内复用
栈内复用,这是一种单实例模式,启动SingleTask模式的Activity A的时候,系统会先查看是否存在A想要的任务栈,如果不存在,则重新创建一个任务栈,同时将创建A的实例放到栈中。如果存在所需的任务栈,如果任务栈中存在A实例,则将A移动到栈顶,clearTop,清掉A上面的Activity,调用onNewIntent方法;如果任务栈中不存在A实例,则创建A实例,并将其放到栈中。
通过taskAffinity声明任务栈,taskAffinity属性和SingleTask启动模式或者allowTaskReparenting属性配对使用,其他情况下没有意义。
singleInstance 单实例
加强版的SingleTask,也是一种单实例模式,并且,只能单独位于一个任务栈中。
启动模式的设置
方式一:在AndroidManifest中进行配置,配置launchModel
方式二:在启动Intent中设置flags的形式设置
设置的效果:方式二 > 方式一
四、Activity 任务栈&四种形态
(1)任务栈是维护activity的栈结构,默认的Activity是在应用栈中,可以通过配置taskAffinity属性,但是,需要当singleTask的时候才生效。
(2)四种形态
- Running/Active 此时,Activity处于任务栈栈顶,可直接和用户交互,处于运行状态。
- Paused:Activity失去焦点,被一个非全屏或者透明主题的Activity覆盖,此时处于Paused状态,不能与用户交互,属于可见状态,但是不是前台状态,内存低的情况下会被回收。
- Stopped:Activity处于停止状态,当被一个非透明主题的Activity完全覆盖的时候。
- Killed:当Activity被系统回收的时候,Activity处于销毁状态。
五、Activity 异常情况下的生命周期
情况一:资源相关的系统配置变化导致Activity被杀掉重启
情况二:内存不足导致优先级低的Activity被杀掉
Activity会回调onSaveInstanceState方法保存View的一些状态,如果是异常被杀死过程,生命周期的调用过程为
onPause -> onSaveInstanceState -> onStop -> onDestroy -> onCreate -> onRestoreInstanceState
可以通过配置AndroidManifest中的Activity属性 configChanges来防止Activity被Kill重启
onSaveInstanceState调用时机:
- 当用户点击HOME键的时候
- 长按HOME键的时候长按HOME键的时候
- 启动另外一个Activity的时候启动另外一个Activity的时候
- 按下电源键的时候按下电源键的时候
- 异常结束Activity的时候异常结束Activity的时候