欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Activity启动模式--《Android开发艺术探索》阅读笔记--第一章part2

程序员文章站 2022-05-14 08:03:10
...

一、LaunchMode

预备知识:任务栈(回退栈),后进先出

1.standard(标准模式):默认启动模式,每创建一个新Activity,都会产生一个新的Activity实例并且放入相应的任务栈中。和典型的栈调用数据类似没多大区别。

2.singleTop(栈顶复用模式):如果要新建的Activity本身已经有一个Activity实例位于栈顶时,那么这个Activity不会被重新创建,而是会回调onNewIntent方法取出当前请求的信息,而这个新建的Activity不会被系统调用onCreate、onStart方法。注意的是,该模式只使用于新Activity已经位于栈顶。否则的话还是会创建新的Activity并且进行压栈操作。

3.singTask(栈内复用模式):只要Activity在想要的任务栈中存在,会将栈内存在的Activity做置顶操作(由于“后进先出”,会clear top)。而如果在栈内不存在时,会直接创建并压栈。具体一点,想要的任务栈如果不存在,则创建一个任务栈然后创建实例入栈;如果想要的任务栈存在,则看是否存在实例,若存在则clearTop且onNewIntent,不存在则创建实例入栈。

4.singleInstance(单实例模式):加强的singleTask模式,除了具有singTask的一切特性外,还加强了一点,就是具有此模式的Activity只能单独的位于一个任务栈中。也就是说,在它启动的时候,系统会为它分配一个新的任务栈。由于singleTask的复用性,在其他需要创建Activity的时候,都不会创建新的Activity。

扩展:TaskAffinity(Activity想要的任务栈

每个Activity都会有TaskAffinity参数,标识了Activity所需要进入的任务栈的名字。默认是包名,也就是当前应用下的任务栈。两种情况(其他情况没有意义):

1.当TaskAffinity和singleTask启动模式配对使用的时候:singleTask的activity会运行在TaskAffinity指定名字的任务栈中。

2.当TaskAffinity与allowTaskReparenting结合的时候:在这种情况下,如果该Activity的allowTaskReparenting设置为true的时候,这个Activity会直接进入后台,直到当和TaskAffinity名字相同的任务栈进入前台的时候,此时的Activity会转移到该任务栈中并处于栈顶位置。 书中例子:先有应用A、B。当在A中启动B的一个ActivityC,然后按Home键回到桌面,打开B应用。此时你会发现显示出来的是ActivityC。

用法<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由两部分组成:mimeTypeURI。其中,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);
}


另外,

Activity启动模式--《Android开发艺术探索》阅读笔记--第一章part2



相关标签: activity