(原创)Activity启动模式详解

前言

我们平常在开发APP时,在配置清单里面注册一个Activity
会经常用到它的launchMode属性
这个其实就是Activity的启动模式
相信这一块大家都不陌生
我们的一个APP启动时,会有一个属于自己的Task任务栈
里面放入的就是我们的Activity
比如我们分别启动了A、B、C三个Activity
那么任务栈就是这样的:
在这里插入图片描述
显示在屏幕的就是页面C
每个Task都会维护自己栈内的Activity
点击返回,就会按照顺序关闭最上层的Activity
这其实就是默认的启动模式standard

taskAffinity

在安卓里,一个APP默认只有一个Task存活在最近任务列表界面
用来区分是否是相同的Task,是根据Task的taskAffinity属性来决定的
一个Task默认使用栈底的Activity的taskAffinity属性来确定自己的taskAffinity属性
而Activity的taskAffinity属性,默认来源于Application的taskAffinity
而Application的taskAffinity属性,默认来源于包名
于是我们可以说:
一个APP里面的Activity,默认情况下,它们的taskAffinity都是包名

standard

standard模式下,每次都会去创建一个新的Activity,然后放入我们的任务栈中,这个不用多介绍
当我们点击最近任务键,就可以看到我们一个个APP的Task任务栈
比如我们打开一个APP,然后按下返回按钮关掉这个APP
会发现最近任务界面,还是有这个APP的Task。
难道APP并没有退出?
其实不是的,此时APP已经退出了
只不过你在最近任务再次点击这个任务栈,
系统会重新帮你创建Activity罢了
这就需要我们知道:
最近任务显示的Task,不代表APP就存活着
同样还有一种场景
如果我们在一个APP里面打开另外一个APP的Activity
启动模式为standard
那么另外一个APP的Activity,也会被放入当前APP的栈顶
就好像这样:
在这里插入图片描述

singleTop

如果Activity的启动模式为singleTop
那么基本和standard是一样的
只不过如果这个Activity在栈顶
那么就不新建,而是走onNewIntent方法

singleTask

如果Activity的启动模式为singleTask,那么当Activity被别的APP启动时
并不会和standard模式一样,放入别的APP的Task
而是直接放入自己的Task
同时连同自己的Task一起堆在别的APP的Task上面
类似下图这样,B进程的Task直接堆在了A进程的Task上面
在这里插入图片描述
这种情况点击返回时
回退的就是B进程的Task的页面
直到B进程回退完,才会显示A进程的Task然后继续回退
直到显示桌面
注意点一:
当你点击Home或者最近任务键时
两个Task就会被拆分开
最近任务列表就变成了下面这样:
在这里插入图片描述
这时候你再点击进入B进程,然后点击返回
当B进程Task的任务都返回后,就会直接显示桌面了
注意点二:
当B进程的这个singleTask的Activity页面已经存在Task里面时
这个Activity不会被再次创建,而是调用自己的onNewIntent方法
同时把压在自己上面的页面给移除掉
让自己显示在Task栈顶
如下图:
在这里插入图片描述
所以,singleTask的Activity
在一个Task里面只有一个
注意点三:
当一个进程A启动singleTask的Activity时
系统会去对比他们的taskAffinity
如果相同:
这种情况就是启动了自己APP里面的singleTask的Activity,直接把Activity放入Task即可
如果不同:
说明是别的APP的Task启动了这个Activity,于是这个Activity拿着自己的taskAffinity去最近任务列表中找。找到了和自己taskAffinity一致的Task,就进入这个Task,找不到,就新建一个Task,把自己丢进去。

singleInstance

singleInstance的Activity更极端
它被启动时,
要自己独占一个Task
然后堆在启动他的Activity所在的Task的上面
如果之前已经创建,也是调用onNewIntent方法进行复用
当点击Home或者最近任务键时
这两个Task也会拆分
如果在singleInstance的Activity上面再启动一个Activity
那么会把这个新启动的Activity的Task栈整个的拿过来
堆在singleInstance的Activity的Task栈上面
如下图:
在这里插入图片描述
这里,如果进程B的Activity不是启动的进程C的Activity
而是又启动了进程A的页面A
那么进程A的Task就会从底部拿出来
然后堆在singleInstance的Task栈上面
Task的堆放情况就会变成这样:
在这里插入图片描述

这里还有一个注意点:
假如B进程已经在最近任务界面有一个Task了
而这个singleInstant的Activity因为和B进程的Task的taskAffinity是一样的
所以这个Activity的Task在最近任务界面是看不到的
因为最近任务针对相同的taskAffinity的Task
只会显示一个
但这个Activity又是实实在在存在的,只是看不见
所以我们也可以说:
在最近任务界面看不到的Task,未必就不存在

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值