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

一、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);
}

 

 

 

 

另外,

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值