一、LaunchMode
预备知识:任务栈(回退栈),后进先出
扩展:TaskAffinity(Activity想要的任务栈) 每个Activity都会有TaskAffinity参数,标识了Activity所需要进入的任务栈的名字。默认是包名,也就是当前应用下的任务栈。两种情况(其他情况没有意义):
用法
<application android:allowTaskReparnting="true/false"></application>
是否允许activity更换从属的任务,比如从短信息任务 切换到浏览器任务。用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。 如果这个特性没有被设定,设定到<application>元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。 一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。 例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。 Actvity的affinity是由taskAffinity特性定义的。Task的affinity是通过读取根Activity的affinity 决定。因此,根据定义,根Activity总是位于相同affinity的Task里。由于启动模式为“singleTask”和 “singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。 注:在Intent中设置标志位来指定启动模式 比 通过AndroidMenifest.xml为Activity指定启动模式 优先级高。 二、IntentFilter匹配规则(隐式启动) IntentFilter的过滤信息包括三种:action、category、data。一个Activity可以设定多个IntentFilter,只要有其中一组IntentFilter完全匹配,可以开启该Activity。 action的匹配规则 action的本质是一个字符串,其作用是描述Intent所触发的动作的名称。在IntentFilter中,我们可以定义多个action,只要有一个action和Intent传递的信息匹配,那么就算配合成功。注意的是,系统本身预定义了一些action,代表可启动的一些预定义的Activity,比如拨号界面等这些预定义的action集中放在android.intent.action下,调用的时候从里面选取,比如Intent.ACTION_CALL category匹配规则 category和action的本质是一致的,但代表的意义不同,category描述的是目标组件的类别信息,表明这个目标可以干些什么。当然,我们也可以给它进行自定义的设置。而关于category的匹配规则,大致如下:如果Intent中含有category,那么不管你有几个,都需要和目标Activity在IntentFilter中设定的category匹配。 data的组成 data由两部分组成:mimeType 和URI。其中,mimeType指的媒体类型,可以表示图片image/jpeg,文本text/html ,音频audio/mpeg4-generic 和视频video/*等。而URI表示统一资源标识符(Uniform Resource Identifier),用以制定所需资源的存储路径。其结构如下:
<scheme>://<host>:<port>:/[<path>|<pathPrefix>|<pathfrefix>]
结构说明如下: scheme:URI的模式,比如http、file等 host:URI的主机名,即当前资源所在的主机的IP地址,可以用域名表示,如www.baidu.com port:URI的端口号,比如80,指获得资源的窗口路径。 path、pathPrefix、pathPattern:表示路径信息 data匹配规则与action类似。
补充:在隐式启动时,可以先判断是否有activity能匹配我们的隐式Intent,方法如下:
Intent intent = new Intent(); intent.setAction("com.hfy.test.action");Intent.ACTION_CALL intent.setDataAndType(Uri.parse("hfy://www.hfy.com"),"text/plain"); intent.addCategory(CATEGORY_DEFAULT); ComponentName componentName = intent.resolveActivity(getPackageManager()); if (componentName != null) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); }