Activity的启动模式:launchMode和intentFlags

启动模式定义了一个新的activity实例与任务栈task的关系,主要有两种方法:

1、直接在Manifast文件设置activity的属性launchMode:

android:launchMode=[“standard” | “singleTop” | “singleTask” | “singleInstance”]

2、在代码里通过context.startActivity(intent)打开新的activity时,设置intent的intentFlags:

intent.setFlags(Intent.*); *主要有FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_SINGLE_TOP、FLAG_ACTIVITY_CLEAR_TOP等。


关于task栈:

当用户按home键返回程序启动器(application launcher),选择了一个新的应用程序(事实上是一个新的task),当前的task就被转移到后台,新的task被显示到屏幕上。默认情况下,一个应用程序中的所有activity都有一个affinity–这让它们属于同一个task。然而,每个activity可以通过<activity>中的taskAffinity属性设置单独的affinity。不同应用程序中的activity可以共享同一个affinity,同一个应用程序中的不同activity也可以设置成不同的affinity。这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根Activity的taskAffinity的值。

affinity属性在2种情况下起作用:当启动activity的Intent对象包含FLAG_ACTIVITY_NEW_TASK标记,或当activity的allowTaskReparenting被设置成true。

第二个比较重要的点是,用户必须能够在离开task之后返回,打个比方,某个activity运行了一个singleInstance模式的activity,初始化了一个新的task,此时用户按下home键时,这个activity就被主屏幕“挡住”了,点击应用程序图标即带有MAIN和LAUNCHER过滤器的那个activity,进入的只是此acitivity所在的task栈,用户再也无法返回到那个新建的activity(不去点击图标而是直接长按home键倒是可以打开)。

通常打开新的activity默认就是push到task中去,按返回键则是pop出来,而设置launchMode和intentFlags就是为了改变这种默认行为。


具体来看四大启动模式:

1、standard:被启动就会创建一个新的

2、singleTop:栈顶单实例(当该activity处于task栈顶时,可以复用,直接onNewIntent)

3、singleTask:栈中单实例(oncreate该activity并销毁在他之上的其他activity)

4、singleInstance:全局单实例(跟singleTask基本上是一样,只有一个区别:在这个模式下的Activity实例所处的task中,只能有这个activity实例,不能有其他的实例。应用场景:地图,Activity初始化需要大量资源)


单独使用launchMode或intentFlags可以实现相同的效果,但两者本质并不相同,前者是activity的属性后者是intent的属性。

常见的intentFlags:

官方文档里介绍FLAG_ACTIVITY_NEW_TASK和singleTask表现相同,FLAG_ACTIVITY_SINGLE_TOP和singleTop表现相同,而FLAG_ACTIVITY_CLEAR_TOP则没有对应的launchMode属性,它表示摧毁目标以及后面的activity然后重新调用onCreate,而如果使用FLAG_ACTIVITY_SINGLE_TOP或singleTop则不会摧毁目标而是调用onNewIntent。

有一个FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK的经典组合用来找到可能在另一个task已经存在的activity。

这个问题还需学习,不同组合的launchMode和intentFlags结果变化很大。


附其他activity属性:

默认情况下当用户长时间离开task(当前task被转移到后台)时,系统会清除task中栈底activity外的所有activity。这样,当用户返回到task时,只留下那个task最初始的activity了。

1、allowTaskReparenting:一般为false,如果栈底activity的这个属性被设置成true后,刚刚描述的情况就不会发生。task中的所有activity将被长时间保存。

2、alwaysRetainTaskState:如果栈底activity的这个属性被设置为true,一旦用户离开task,则task栈中的activity将被清空到只剩下栈底activity,即使用户只是短暂地离开。

3、finishOnTaskLaunch:这个属性与clearTaskOnLaunch相似,但它只对单独的activity操作,而不是整个task。它可以结束任何activity,包括栈底的activity。当它设置为true时,当前的activity只在当前会话期间作为task的一部分存在,当用户退出activity再返回时,它将不存在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值