1. Activity的启动模式
-
standard
标准模式,不指定的话默认的模式,A启动B,B就会进入到A所在的栈中,放在A的上层,出栈时B先出,即先入后出。这种模式下要求Context必须为Activity类型的,即必须保证当前Activity已经入栈,否则的话就会报错,如下图:
上面异常信息说明,要想以ApplicationContext启动Activity的话,需要添加FLAG_ACTIVITY_NEW_TASK属性,为被启动的Activity创建一个新栈。标准模式下,每一次启动都会新建一个Activity实例放入栈中,比如A以标准模式启动了5次,那么对应的栈中就有5个A的实例。
-
singleTop
栈顶复用模式,如果A在栈顶,那么再次以singleTop模式启动A的话,A实例就不会被重复创建,当然A的onCreate()、onStart()也不会被系统调用,此时A的onNewIntent()方法会被调用。比如,启动A后,在A中又以singleTop模式启动A:
可见,A没有被重新创建,A的onNewIntent()方法被执行了。
-
singleTask
栈内复用模式,同singleTop一样,实例的onNewIntent()方法会被调用,这种模式也分为几种情况:
① S1栈中ABC,D以singleTask模式启动,如果不为D指定新的栈,那么D就会默认进入S1栈内,位于栈顶
可见,ABCD都在S1栈中,如果此时在D中以singleTask模式启动B,因为B已经在栈S1中,此时由于singleTask自带clearTop效果,启动B之后,栈S1中只有AB实例,CD都已经被清出S1栈了
② S1栈中ABC,D需要新栈S2,以singleTask模式启动D,系统会先创建新栈S2,并新建实例D放入S2中
taskAffinity属性可以为实例指定新的栈。打印一下D当前的栈:
可见,D所在的栈与ABC不一致。
-
singleInstance
单实例模式,以此模式启动的Activity每次都会新建一个栈来存放实例,它具有singleTask的所有特性
2. Activity的匹配规则
-
action匹配规则
action是一个字符串
匹配规则:Intent中设置的action必须能够和过滤规则中的action匹配,这种匹配意思是完全一致,大小写一致,否则不能匹配成功;另外,如果过滤规则中有多个action,那么Intent中设置的action只需要与其中一个action完全匹配即可。
-
category匹配规则
category是一个字符串
匹配规则:Intent中如果设置了category,那么匹配规则中必须存在与之对应的category;另外,如果Intent没有设置category,在调用startActivity或者startActivityForResult方法时系统会默认为其加上“android.intent.category.DEFAULT”这个category,因此也必须在匹配规则中添加默认category方能匹配成功。
-
data匹配规则
如果过滤规则中添加了data,那么Intent中也必须要定义可匹配的data
data由两部分组成:mimeType和URI。
mimeType表示媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,表示图片、文本、视频等不同的媒体格式。
URI结构:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>] 举例: content://com.example.project:200/folder/subfolder/etc http://www.baidu.com:80/search/info
scheme:URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么整个URI的其他参数无效,也就意味着URI是无效的。
host:URI的主机名,比如www.baidu.com,如果host未指定,那么整个URI的其他参数无效,这也意味着URI是无效的。
port:URI的端口号,比如8080,仅当URI中指定了scheme和host参数的时候port参数才有意义。
path、pathPrefix和pathPattern:这三个参数表述路径信息,其中path表示完整的路径信息;pathPattern也表示完整的路径信息,但是它里面可以包含通配符“*”;pathPrefix表示路径的前缀信息。
匹配规则中data里面只要添加了相应属性的设置,那么在Intent中就必须通过setDataAndType方法设置对用的信息方能匹配成功。另外,为了检测是否匹配到对应的Activity,可以使用PackageManager的resolveActivity方法检测,只要返回结果不为null就表示匹配成功了。