一、Activity的生命周期全面分析
1、典型情况下的生命周期分析
a. onCreate()
Activity正在被创建,做初始化工作,如setContentView加载界面布局资源、初始化数据。
b. onStart()
Activity正在被启动,此时Activity已经可见但未出现在前台,无法和用户交互。
c. onResume()
Activity可见,出现在前台并开始活动。
d. onPause()
Activity正在停止,此时可以做一些存储数据、停止动画等不太耗时的操作。注意:旧Activity的onPause执行完,新Activity的onResume才会执行。
e. onStop()
Activity即将停止,可做稍微重量级的回收工作,如取消网络连接、注销广播接收器等。
f. onDestroy()
Activity即将被销毁,可以做一些回收工作和最终的资源释放。
g. onRestart()
Activity正在重新启动,当前Activity从不可见重新变为可见状态时调用。
说明:onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的,在实际使用中没有其他明显区别。
2、Activity生命周期切换过程
(1)一个Activity的启动顺序:onCreate -> onStart -> onResume
(2)切换到新的Activity:旧Activity的onPause() -->新Activity的onCreate()–>onStart()–>onResume()–>旧Activity的onStop()
(3)回到原Activity:新Activity的onPause()–>旧Activity的onRestart()–>onStart()–>onResume()–>新Activity的onStop()–>onDestory();
(4)按back键回退:onPause -> onStop -> onDestroy
(5)HOME键的执行顺序:onPause->onStop->
onRestart->onStart->onResume
(6)Activity1上弹出对话框Activity2:Activity1的onPause()–>Activity2的onCreate()–>onStart()–>onResume()
(7)弹出对话框时关闭屏幕:Activity2的onPause()–>onStop()–>Activity1的onStop()
(8)此时点亮屏幕:Activity2的onRestart()–>onStart()–>Activity1的onRestart()–>onStart()–>Activity2的onResume()
(9)关闭对话框Activity2:Activity2的onPause()–>Activity1的onResume()–>Activity2的onStop()–>onDestroy()
(10)销毁Activity:onPause()–>onStop()–>onDestroy()
3、异常情况下的生命周期分析
a. 资源相关的系统配置发生改变导致Activity被杀死并重新创建
例如屏幕发生旋转:当竖屏切换到横屏时,会先调用onSaveInstanceState来保存当前Activity的状态,接着销毁当前的Activity,然后重新创建一个Activity,当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。
onSaveInstanceState->onPause->onStop->
onDestroy->onCreate->onStart->onRestoreInstanceState->onResume
说明:onSaveInstanceStat它既可能在onPause之前调用,也可能在onPause之后调用,但只会出现在Activity被异常终止的情况下。
b. 资源内存不足导致低优先级的Activity被杀死
(1)Activity优先级排序:
前台可见Activity>前台可见不可交互Activity(前台Activity弹出Dialog)>后台Activity(用户按下Home键、切换到其他应用)
(2)当系统内存不足时,会按照Activity优先级从低到高去杀死目标Activity所在的进程。
(3)若一个进程没有四大组件在执行,那么这个进程将很快被系统杀死。
二、Activity启动模式
1、设置Activity启动模式的方法
a.在AndroidManifest.xml中给对应的Activity设定属性android:launchMode=“standard|singleInstance|single Task|singleTop”
b.通过标记位设定,方法是intent.addFlags(Intent.xxx)
2、Activity的LaunchMode
a. standard:标准模式、默认模式
含义:每次启动一个Activity就会创建一个新的实例。
注意:使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认会进入启动它的Activity所属的任务栈中,但是由于非Activity的Context没有所谓的任务栈。
解决方案:为待启动Activity指定FLAG_ACTIVITY_NEW_TASK标记位,此时待启动Activity是以singleTask模式启动的。
b. singleTop:栈顶复用模式
含义:如果新Activity已经位于任务栈的栈顶,就不会重新创建,并回调onNewIntent(intent)方法。
c. singleTask:栈内复用模式
含义:系统会先确认它所需任务栈已经创建,否则先创建任务栈,然后放入Activity,如果栈中已经有一个Activity实例,那么这个Activity就会被调到栈顶。只要该Activity在一个任务栈中存在,都不会重新创建,并回调onNewIntent(intent)方法。
TaskAffinity参数标识了一个Activity所需要的任务栈的名字。默认情况下,所有Activity所需的任务栈的名字为应用的包名。
d. singleInstance:单实例模式
含义: 具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。
3、Activity的Flags
- FLAG_ACTIVITY_NEW_TASK 指定“singleTask”启动模式
- FLAG_ACTIVITY_SINGLE_TOP 指定“singleTop”启动模式
- FLAG_ACTIVITY_CLEAR_TOP 具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 具有这个标记的Activity不会出现在历史Activity的列表中
4、IntentFilter的匹配规则
原则:(1)一个intent只有同时匹配某个Activity的intent-filter中的action、category、data才算完全匹配,才能启动该Activity。(2) 一个Activity可以有多个 intent-filter,一个 intent只要成功匹配任意一组 intent-filter,就可以启动该Activity。
a. action匹配规则:
- 要求Intent中必须有一个action且必须和intent-filter中的其中一个 action相同
- 区分大小写
b. category匹配规则:
- intent中的category可以不存在,这是因为系统在调用startActivity或者startActivityForResult的时候会默认为Intent加上 < category android:name=“android.intent.category.DEAFAULT” /> 属性值。
- Intent中如果含有category,则要求intent中出现的每个category都必须和intent-filter中的其中一个category 相同。
c. data匹配规则:
- 如果intent-filter中有定义data,那么Intent中也必须也要定义可匹配的data。
- data主要由mimeType(媒体类型)和URI组成。在匹配时通过intent.setDataAndType(Uri data, String type)方法对data进行设置。
说明:
uri包含的内容有:<scheme>://<host>:<port>/[<path>|<pathPattern|pathPrefix>]
其中 scheme表示资源类型,可以是http、content、file等类型,host为主机名、port为端口、path为资源路径完整信息,pathPatern是可以包含通配符的路径,pathPrefix为前缀。
URI的默认值为content和file。也就是说,虽然没有指定URI,但是Intent中的URI部分的schema必须为content或者file才能匹配