Android四大启动模式
Posted andy连长
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android四大启动模式相关的知识,希望对你有一定的参考价值。
一、启动模式概述
了解Activity启动模式之前,先介绍一下android中task容器栈,其实,就是Activity的一个容器集合,所有的Activity实例都是存放在这个容器栈里面。其实就是数据结构中栈是一个原理:先进后出,后进先出,所有操作都是发生在栈顶。 做Android开发朋友都应该知道,应用中每个有效的Activity组件都必须需要在AndroidManifest.xml工程配置文件夹中注册声明。在里面中有很多属性我们可以去配置,如果不配置就使用系统默认的配置属性。其中,我们今天要讨论的Activity启动模式就是属于Activity配置属性之一,叫launchMode,它具有四种启动模式,分别是:1.standard,2.singleTop,3.singleTask,4.singleInstance,一般如果不显示声明,默认为standard模式。
二、启动模式作用
launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。
三、分别详细介绍每种启动模式
1、standard
standard模式是默认的启动模式,不用为<activity>配置android:launchMode属性即可,当然也可以指定值为standard。 standard模式是所启动的Activity都是在同一个task容器栈下,不会重新创建新的task容器栈。先压入栈的Activity实例按顺序入栈底,后入栈在栈顶,处于栈的顶部Activity实例处于活动状态,其他处于非活动状态。按物理返回键,退出当前所处活动状态Activity窗口,这样就会从task容器栈中弹出,显示在手机主屏幕上,从而,有非活动状态转换成活动的状态。其次,standard容器栈可能会存在着相同的Activity实例,只有每调用一次startActivity方法,就会创建目标Activity实例对象压入task容器栈。
注意:在不指定启动模式的前提下,系统默认使用该模式启动Activity,每次启动一个Activity都会重写创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。
总结:standard,标准模式,每次启动都会创建新的实例,不管实例是否存在
2、singleTop
AndroidManifest.xml文件中<activity>launchmode属性配置singletop,那么启动实例化Activity,如果task容器栈顶存在已经激活的Activity实例,就会重用当前栈顶的Activity实例,不会再重新去实例化Activity对象。善于思考的朋友可能会问,如果要启动的目标Activity已经有实例化对象存在task容器栈里面,只是现在不处于栈顶,这样情况下,singletop启动模式会创建目标Activity实例吗?答案是肯定的。要启动的目标Activity实例正好处于栈顶,才能重用该实例,其他情况必须创建新实例。
注意:这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。
总结: singleTop,栈顶复用,如果Activity处于栈顶,则不会创建新的Activity
singleTop模式分3种情况
- 当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
- 当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
- 当前栈中不存在该Activity的实例时,其行为同standard启动模式
standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task,即使你指定了taskAffinity属性。
那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。
- 这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名
- 我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值
- 一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
- 在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务
- 为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task
3、singleTask
singletask模式,特别需要注意了。启动的目标Activity实例如果已经存在task容器栈中,不管当前实例处于栈的任何位置,是栈顶也好,栈底也好,还是处于栈中间,只要目标Activity实例处于task容器栈中,都可以重用该Activity实例对象,然后,把处于该Activity实例对象上面全部Activity实例清除掉,并且,task容器栈中永远只有唯一实例对象,不会存在两个相同的实例对象。所以,如果你想你的应用不管怎么启动目标Activity,都只有唯一一个实例对象,就使用这种启动模式。
注意:这个模式十分复杂,有各式各样的组合。在这个模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。
singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈
- 如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去
- 如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例
如果存在实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法
如果不存在该实例,则新建Activity,并入栈
此外,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去。
4、singleInstance
singleInstance启动模式,简单说就是可以共享某个Activity。比如,应用1的任务容器栈中创建了MainActivity实例,应用2也要激活MainActivity,则不需要创建MainActivity实例,直接可以公用MainActivity实例。 尤其值得注意:应用1启动MainActivity,按home键;打开应用2启动应用1的MainActivity实例。再按home键,打开应用1,这时候应用1的界面是应该是处于MainActivity界面实例。
注意:该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
总结:singleInstance,在singleTask的基础上,限制了此模式的Activity只能单独地位于一个任务栈中。
四、总结
总之,Android四大启动模式相当简单。默认standard模式,他是task容器栈可能存在相同的Activity实例;singletop模式下,重用栈顶Activity实例,栈顶不存在,则创建新的Activity实例,该模式下有可能存在相同Activity实例;singletask模式,task容器栈存在目标Activity实例,则重用该实例,task容器栈永远只有唯一activity实例,并且,其余是Activity实例被清除掉。singleinstance模式,不同应用可以共享Activity实例,并且是处于不同容器栈中。
以上是关于Android四大启动模式的主要内容,如果未能解决你的问题,请参考以下文章