Activity 四种启动模式以及应用场景

Activity有四种启动模式,在介绍这四种启动模式之前,我们需要先知道,为什么Google会为Activity设置四种启动模式呢?

我们先来介绍一个概念:任务栈

任务栈:

1,程序在创建时,会创建一个任务栈,这个任务栈的作用是用来存储启动和创建的Activity

2,此任务栈包含了一个集合,让存储的任务栈给用户有序的列出来,以至于不丢失他们的状态

3,任务栈用来保存Activity的状态

4,退出程序时,清除任务栈中的Activity,任务栈销毁,程序退出

任务栈的缺点: 
1,每开启一次页面都会在任务栈中添加一个Activity,而只有任务栈中的Activity全部清除出栈时,任务栈被销毁,程序才会退出,这样就造成了用,户体验差, 需要点击多次返回才可以把程序退出了。 
2,每开启一次页面都会在任务栈中添加一个Activity还会造成数据冗余, 重复数据太多, 会导致内存溢出的问题(OOM)。

 

为了解决任务栈的缺陷,Google才设置了四种启动模式

这四种启动模式如下:

  • standard
  • singleTop
  • singleTask
  • singleInstance

 

下面我们来介绍一下这四种启动模式在什么样的场景下使用?

  1. Standard

standard模式是默认的启动模式,不用为配置android:launchMode属性即可,当然也可以指定值为standard。

这个我们就不详细介绍了,平时我们用的都是这样的

standard的原理如下:

standard不管是否已经有了实例,都会进行创建,他们在任务栈中的序列号并不一样,每一次创建,都是一个全新的Activity

    2.singleTop

如上的原理图,如果我们在清单文件中声明此Activity启动模式是singleTop的话,这样的情况下,singleTop定义的Activity跳转,将不会是重新创建的Actiivty,观看他们在栈中的序列号就可以知道了

singleTop的原理图如下:

当然,这只是一个Activity的情况,那如果是多个Activity的情况下,他们之间的跳转又是什么样的呢?

我们通过打印他们跳转的Activity在栈中的序列号发现,FirstActivity跳转到SecondActiivty,再从SecondAcitivty跳转到FirstActivity时,他们所产生的序列号并不一样,这就证明,在SingleTop的模式下,当你不同Activity之间的跳转的时候,还是会新建一个Acitivyt的实例的

这时候的原理图如下:

在任务栈中的判断就是,当前的栈顶元素并不是FirstActivity,所以当你跳转时,他就会自动创建一个新的实例,压入栈顶

所以,SingleTop模式使用场景就是,如果当前的Activity是在栈顶的情况下,则重复使用,如果不在栈顶的情况下,则重新创建,比如说,我们写一个通讯的页面,接收到消息之后,弹出一个Activity,这个Activity是用来显示消息列表的,如果来了十条消息,我们还是用这个Activity来显示,总不能来了十条消息,就显示十个Activity吧?

   3.singleTask

将上面的两个实例中FirstActivty的启动模式改为singleTask,打印之后发现,FirstActivty的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivty时,没有生成新的实例,但是从MainActivity跳转到SecondActivity时生成了新的实例。

原理图如下:

SecondActivity跳转到FirstActivty后的栈结构变化的结果,我们注意到,SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivty之上的Activity实例统统出栈,将FirstActivty变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivty时,SecondActivity实例都被迫出栈,下次等FirstActivty跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。 
这就是singleTask模式,如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。

总之一句话,保证这种启动模式的Activity一直处于栈顶的位置,

singleTask适合作为程序入口点。例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。之前打开过的页面,打开之前的页面就ok,不再新建。

   4,singleInstance

这种启动模式比较特殊,因为它会启用一个新的栈结构,将Activity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。 

我们修改FirstActivity的launchMode=”standard”,SecondActivity的launchMode=”singleInstance”

原理图如下:

我们看到从MainActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到MainActivity,这个时候系统会在原始栈结构中生成一个MainActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到MainActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。

 

 

singleInstance适合需要与程序分离开的页面。例如闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。

 

最后,附上一张Activity的启动流程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值