Activity的四种启动模式

前言:

 Activity为什么会有启动模式? 我们可以想想Activity作为Android四大组件中使用最多的一个,经常需要使用Activity将界面显示给用户,这也就设计到了Activity的频繁创建新的Activity(切换Activity)或是已经启动的Activity再次启动(切换回来)。尽管Activity有完整的生命周期回调,但系统又是通过什么来管理众多的Activity的呢?答案是Activity任务栈。Activity任务栈是一种栈结构,先进后出,后进先出,通过任务栈结构可以有效地管理众多的Activity并适应不同的功能需求(有些特殊的需求可以通过不同的启动模式来实现)。下面将介绍Activity的四种启动模式(LaunchMode)。

1、standard(标准)模式

 如果我们没有指定Activity的启动模式的时候系统默认以standard模式启动我们的Activity,所以我们平时开发的时候也没有去指定Activity的启动模式,但有些特色功能需求需要使用特定的启动模式来完成,我们可以在注册Activity的时候通过launchMode属性来指定特定的启动模式

 在这种模式下,每当我们启动一个Activity的时候,系统都会创建这个Activity的实例,尽管我们之前启动过,如我们在A中启动A,在启动的A中又启动A,那么任务栈中的Activity就是AAA,即会有3个相同的Activity的实例。代码演示如下:

public void next(View v){
    startActivity(new Intent(this,MainActivity.class));
}

 通过这个按钮的方法启动3次相同的Activity,那么可以通过adb shell dumpsys activity命令查看任务栈的状态,可以发现任务栈中存在3个MainActivity的实例,这时我们需要点击3次返回键才能推出这个应用 。

adb shell dumpsys activity

这里写图片描述

2、singleTop(栈顶复用)模式

 顶部单一,也就是栈顶单一,意思是保证 Activity的实例在栈顶是单一的,具体点就是当我们以singleTop模式启动一个Activity的时候,如果这个Activity已经在当前栈顶了,那么将不会再次创建这个Activity的实例(相反则会创建),而是直接调用栈顶的那个实例,如栈顶是ABC,这时启动C,则栈顶还是ABC,C还是之前的那个实例,相比standrad模式则同一个任务栈AAA(A的启动模式为singleTop)的情况是不可能存在的了,而会存在ABCA(A的启动模式为singleTop)的情况。

3、singleTask(栈内复用)模式

 栈内单一,指的是Activity的实例在栈内是单一的,当然不同栈还可以存在它的实例。同时,这种模式默认具有clearTop的效果,当要启动的Activity在栈中存在实例时,会将这个Activity调至栈顶,并将位于它之上的Activity出栈,如:栈中存在的Activity实例为ABCD,这时如果D启动B,则栈中的情况为AB。而相比singleTop,singleTask中ABCA的情况是不存在了(A的启动模式为singleTask)。

如:这里有四个Activity,MainActivity,SecondActivity,ThirdActivity,FourthActivity。

它们依次启动下一个Activity,其中SecondActivity的启动模式为singleTask:

这里写图片描述

adb shell dumpsys activity

这里写图片描述

这时在FourthActivity中启动SecondActivity,再执行adb shell dumpsys Activity

这里写图片描述

 可以看到,这时位于SecondActivity之上的Activity已经全部出栈了,即clearTop的效果。同时taskAffinity属性可以为这种模式的Activity指定任务栈名称(可以和已有的相同,但没意义;名称相同的栈不一定是同一个栈,需要看栈的id是否相同),默认的任务栈名称为应用的包名。

4、singleInstance(栈间复用)模式

 栈间复用,单一实例,在这种模式下Activity只能单独位于一个栈中,当再次启动这个Activity的时候不会再创建它的实例了,尽管它们不在同一栈中。可以理解为全局单例,这种模式使得不同应用可以共享一个Activity的实例。

 如两个应用A和B,B中启动了singleInstance的Acitivity C,这时A也启动B中的C(可以通过隐式启动),那么C不会再创建新实例而是返回B创建的那个实例。

这里写图片描述

可以看到两个应用都启动了ThirdActivity,但栈中只有一个ThirdActivity实例。

任务栈及任务栈转移

 Activity系统通过任务栈管理Activity,每个Activity都有它的任务栈,默认情况是新启动的Activity所在的任务栈是启动它的那个Activity的那个任务栈。你也许在开发中遇到过如下错误:

这里写图片描述

 这个错误意思是通过startActivity启动一个新的Activity需要一个Activity类型的Context(getApplicationContext就会报错),解决办法是给intent设置一个flag,或是将启动模式设置为singleTask

Intent intent = new Intent(this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);

 Activity还有一个allowTaskReparenting属性,这个属性标识是否允许任务栈转移。如,应用A启动了应用B的ThirdActivity(隐式启动),ThirdActivity的启动模式为standard,allowTaskReparenting属性为true,这时由于B应用尚未启动,所以ThirdActivity不可能在B的任务栈中,而ThirdActivity会在启动它的Activity的那个任务栈(正常情况下,B的Activity是不会跑在A的任务栈中),如下图所示:

这里写图片描述

 可以看到,B的ThirdActivity在A的任务栈中,这时我们按下Home键回到桌面,启动应用B,这时,B不是进入MainActivity,而是显示已经被A打开的ThirdActivity,而此时ThirdActivity所在的任务栈已经被转移了,如下图:

这里写图片描述

 任务栈是否转移跟launchMode,taskAffinity,allowTaskReparenting属性有关,其中singleTask及singleInstance下不会发生任务栈转移。

利用singleTask实现一键返回首页的功能

 一键返回首页的功能在开发中很常见,比如一个购物app,从商品首页到商品详情再到最终付款完成,这时要求在付款成功页面返回首页。由于付款成功页面和首页之间存在许多的Activity,这时我们可以将首页Activity的启动模式设置为singleTask,然后在付款成功页面那里添加一个按钮,点击即启动首页Activity即完成了一键返回首页的功能(其他已经打开的Activity已经被关闭了,直接跳到了首页),利用singleTask模式是不是很简单就实现了一键返回首页的功能呢?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值