Activity的启动模式
首先要了解下activity的管理方式,activity存放在Task任务栈中,只有在栈顶的activity才可以与用户交互,打开一个activity就是入栈,退出一个activity就是出栈。在一个app中可能不止一个任务栈,如果该app不与其他app通信交互,则一般情况下只有一个任务栈,但是有时候一个task中activity可能来自不同的app,同一个app中的activity也可能不在同一个栈中。
Standard模式
标准模式,系统的默认方式,每次启动一个activity都会新建一个activity,不管activity是否已经存在。在这种模式下,谁启动了activity,activity就运行在启动它的那个任务栈中。
SingleTop模式
栈顶复用模式。如果新activity已经在栈顶则不会重建。如果新activity不在栈顶,则依然会重建。
SingleTask模式
栈内复用模式,是一种单实例模式。只要activity在一个栈中存在,多次启动都不会重建。这个任务栈可能是自己app内的,也可以是其他app中的栈。如果没有找到activity所需的任务栈,则会为activity新建一个栈,并创建activity实例,如果找到了这个任务栈,但是栈内没有activity实例,则依然会新建一个activity实例。
这里涉及到taskAffinity(任务亲和性,任务相关性)的概念。这个参数标识了一个activity所需要的任务栈的名字。默认情况下,所有activity所需的任务栈的名字为packageName.也可以单独为每个activity指定额外的taskAffinity,但是一定不能和包名相同,不然无意义。
当taskAffinity和singleTask配对使用时,待启动的activity会运行在名字和taskAffinity相同的任务栈中。
当taskAffinity和allowTaskReparenting配对使用时,这种情况比较复杂,一般是跨应用的startActivity。allowTaskReparenting字面意思是是否允许重新寻找任务栈(宿主,父亲),如果设置为true,当一个和它有相同taskAffinity的Task进入前台时,它会重新宿主,进入到该前台Task中。
singleInstance模式
加强的singleTask模式。具有这种模式的activity只能单独地存在于一个任务栈中。例如activityA是singleInstance模式,当A启动后,系统会为它单独创建一个Task,然后A会独自在这个新的栈中(好孤独啊),由于栈内复用,后面的多次请求都不会新建A的实例。
设置启动模式的方式:1.在AndroidManifest.xml文件中设置android:LaunchMode=“singleTask”
2.通过Intent设置flag标志位来指定
第二种方式的优先级高于第一种方式。第二种方式无法为activity指定singleInstance模式
Activity中的Flags
activity的flags有很多,它的作用也有很多,有的可以设置activity的启动模式,有的可以影响activity的运行状态。很多情况下不需要手动设置flag,有些是系统内部调用的。
常用的flags:
-
FLAG_ACTIVITY_NEW_TASK
为activity指定singleTask模式
-
FLAG_ACTIVITY_SINGLE_TOP
为activity指定singleTop模式
-
FLAG_ACTIVITY_CLEAR_TOP
具有此flag的activity在启动时,和它在同一任务栈中的位于它上面的所有activity都要出栈。
IntentFilter的匹配规则
启动activity可以显示启动和隐式启动。隐式启动需要Intent匹配目标组件的InterFilter中设置的过滤信息。IntentFilter中的过滤信息有action,category,data.一个IntentFileter中的action,category,data可以有多个,只有一个Intent同时匹配action类别,category类别,data类别才算完全匹配。一个activity中可以有多个intent-filter,只要能匹配任何一组intent-filter就可以启动对应的activity.
-
action的匹配规则
action是一个字符串,系统预定义了一些action,也可以自定义。一个intent-filter中可以有多个action,只要Intent中的action能够和intent-filter中的任何一个action相同就可匹配成功。如果Intent没有指定action则匹配失败。注意action区分大小写。
-
category的匹配规则
它也是一个字符串,系统预定义了一些category,也可自定义。如果Intent中指定了category,则所有的category都必须是intent-filter中定义了的category.也就是Intent中设置的category必须是中category的子集。Intent可以不设置category,因为系统有默认的category.所以为了使activity能够隐式启动,要在中添加“android.intent.category.DEFAULT”这个category.
-
data的匹配规则
data的匹配规则与action类似。