Activity的启动模式,任务栈Task,intent的Flags

一、相关概念

application翻译成中文时一般称为“应用”或“应用程序”,在android中,总体来说一个应用就是一组组件的集合而task是在程序运行时,只针对activity的概念。说白了,task是一组相互关联的activity的集合,它是存在于framework层的一个概念,控制界面的跳转和返回。这个task存在于一个称为back stack的数据结构中,也就是说,framework是以栈的形式管理用户开启的activity。这个栈的基本行为是,当用户在多个activity之间跳转时,执行压栈操作,当用户按返回键时,执行出栈操作。 

task是可以跨应用的,这正是task存在的一个重要原因。有的Activity,虽然不在同一个app中,但为了保持用户操作的连贯性,把他们放在同一个任务中。例如,在我们的应用中的一个Activity A中点击发送邮件,会启动邮件程序的一个Activity B来发送邮件,这两个activity是存在于不同app中的,但是被系统放在一个任务中,这样当发送完邮件后,用户按back键返回,可以返回到原来的Activity A中,这样就确保了用户体验。

process一般翻译成进程,进程是操作系统内核中的一个概念,表示直接受内核调度的执行单位。在应用程序的角度看,我们用java编写的应用程序,运行在dalvik虚拟机中,可以认为一个运行中的dalvik虚拟机实例占有一个进程,所以,在默认情况下,一个应用程序的所有组件运行在同一个进程中。但是这种情况也有例外,即,应用程序中的不同组件可以运行在不同的进程中。只需要在manifest中用process属性指定组件所运行的进程的名字。

任务(Task)不仅可以跨应用(Application),还可以跨进程(Process)

二、

intent.setFlags和manifest中设置launchMode并不等同,即使两者的值相似,效果也不完全等效,并且intent.setFlags仅对当次操作有效,launchMode是对每次intent跳转都有效。

Intent几种常见flags:

在android.content.Intent中定义了若干个flags,其中最重要的有以下几个:

1.FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。特此说明:FLAG_ACTIVITY_NEW_TASK和singleTask并不等同,把启动模式设置为singleTask,framework在启动该activity时只会把它标示为可在一个新任务中启动,至于是否在一个新任务中启动,还要受其他条件的限制。在使用singleTask和FLAG_ACTIVITY_NEW_TASK时,要仔细测试应用程序


2.FLAG_ACTIVITY_CLEAR_TOP当Intent对象包含这个标记时,如果在栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶。例如:我们的FirstActivity跳转到SecondActivity,SecondActivity跳转到ThirdActivity,而ThirdActivity又跳到SecondActivity,那么ThirdActivity实例将被弹出栈,使SecondActivity处于栈顶,显示到幕前,栈内只剩下FirstActivity和SecondActivity。这个SecondActivity既可以在onNewIntent()中接收到传来的Intent,也可以把自己销毁之后重新启动来接受这个Intent。在使用默认的“standard”启动模式下,如果没有在Intent使用到FLAG_ACTIVITY_SINGLE_TOP标记,那么它将关闭后重建,如果使用了这个FLAG_ACTIVITY_SINGLE_TOP标记,则会使用已存在的实例;对于其他启动模式,无需再使用FLAG_ACTIVITY_SINGLE_TOP,它都将使用已存在的实例,Intent会被传递到这个实例的onNewIntent()中。

A-->B-->C-->D-->A
其中, D-->A,D中按钮的点击事件逻辑, 
Intent intent = new Intent(this, A.class);  
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);  
startActivity(intent);  
注意, 是一个|,  而不是 ||
如果有intent有数据传递, 那么在A的onNewIntent中获取;如果Task中有多个A的实例, 那么会复用最上面的那个,栈下面的其余的不受影响,类似singleTop
如果Flag只有FLAG_ACTIVITY_CLEAR_TOP, 那么A会销毁重建,重走生命周期, intent有数据传递, 那么在A的onCreate中获取;


taskAffinity和allowTaskReparenting结合使用

allowTaskReparenting属性,它的主要作用是activity的迁移,即从一个task迁移到另一个task,这个迁移跟activity的taskAffinity有关。当allowTaskReparenting的值为“true”时,则表示Activity能从启动的Task移动到有着affinity的Task(当这个Task进入到前台时),当allowTaskReparenting的值为“false”,表示它必须呆在启动时呆在的那个Task里。如果这个特性没有被设定,元素(当然也可以作用在每次activity元素上)上的allowTaskReparenting属性的值会应用到Activity上。默认值为“false”。这样说可能还比较难理解,我们举个例子,比如现在有两个应用A和B,A启动了B的一个ActivityC,然后按Home键回到桌面,再单击B应用时,如果此时,allowTaskReparenting的值为“true”,那么这个时候并不会启动B的主Activity,而是直接显示已被应用A启动的ActivityC,我们也可以认为ActivityC从A的任务栈转移到了B的任务栈中。

启动模式launchMode

singleInstance特点可以归结为以下三条:

  1. 以singleInstance模式启动的Activity具有全局唯一性,即整个系统中只会存在一个这样的实例
  2. 以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中(官方文档上的描述为,singleInstance模式的Activity不允许其他Activity和它共存在一个任务中)
  3. 被singleInstance模式的Activity开启的其他activity,能够开启一个新任务,但不一定开启新的任务,也可能在已有的一个任务中开启

被启动模式为singleInstance类型的Activity A 启动的Activity B,framework会检索是否已经存在了一个affinity为Activity B 的taskAffinity属性的任务Task,

1、如果存在这样的一个任务,则检查在这个任务中是否已经有了一个Activity B的实例,

如果已经存在一个Activity B的实例,则会重用这个任务和任务中的Activity B实例,将这个任务调到前台( )。

如果不存在一个Activity B的实例,会在这个任务中创建Activity B的实例,并调用onCreate()方法。

2、如果不存在这样的一个任务,会创建一个新的affinity为Activity B 的taskAffinity属性的任务,并且将Activity B启动到这个新的任务中


本文参考网上多篇现有博文,并加上一些自己的理解、验证和修正,再次感谢原作者。

原文地址:

http://blog.csdn.net/liuhe688/article/details/6761337 

http://blog.csdn.net/zhangjg_blog/article/details/10923643

http://blog.csdn.net/javazejian/article/details/52072131


PS:有错误之处,欢迎指正。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值