Android 任务栈
1. android任务栈又称为Task,它是一个栈结构,具有后进先出的特性,用于存放我们的Activity组件。
2. 我们每次打开一个新的Activity或者退出当前Activity都会在一个称为任务栈的结构中添加或者减少
一个Activity组件,因此一个任务栈包含了一个activity的集合, android系统可以通过Task有序地管
理每个activity,并决定哪个Activity与用户进行交互:只有在任务栈栈顶的activity才可以跟用户进行
交互。
3. 在我们退出应用程序时,必须把所有的任务栈中所有的activity清除出栈时,任务栈才会被销毁。当然
任务栈也可以移动到后台, 并且保留了每一个activity的状态. 可以有序的给用户列出它们的任务, 同时
也不会丢失Activity的状态信息。
4. 需要注意的是,一个App中可能不止一个任务栈,某些特殊情况下,单独一个Actvity可以独享一个任
务栈。还有一点就是一个Task中的Actvity可以来自不同的App,同一个App的Activity也可能不在
一个Task中。
为什么需要Activity的启动模式?
我们在开发项目的过程中,一般都需要在本应用中多个Activity组件之间的跳转,也可能需要在本应用中打开其它应用的可复用的Activity。如我们可能需要跳转到原来某个Activity实例,此时我们更希望这个Activity可以被重用而不是创建一个新的 Activity,但根据Android系统的默认行为,确实每次都会为我们创建一个新的Activity并添加到Task中,这样android系统是不是很傻?还有一点就是在我们每开启一次页面加入到任务栈Task中后,一个Activity的数据和信息状态都将会被保留,这样会造成数据冗余, 重复数据太多, 最终还可能导致内存溢出的问题(OOM)。为了解决这些问题,android系统提供了一套Activity的启动模式来修改系统Activity的默认启动行为。目前启动模式有四种,分别是standard,singleTop,singTask和singleInstance
Standard 模式
又称为标准模式,也是系统的默认模式(可以不指定),在这样模式下,不管栈中是否存在这个实例,每启动一个Activity都会重新创建一个Activity的新实例,这个时候Activity的onCreate、onStart、onResume方法都会被调用
singleTop 模式
又称栈顶复用模式,在这种模式下,如果有新的Activity已经存在任务栈的栈顶,那么此Activity就不会被重新创建新实例,而是复用已存在任务栈栈顶的Activity。这里重点是位于栈顶,才会被复用,如果新的Activity的实例已存在但没有位于栈顶,那么新的Activity仍然会被重建。需要注意的是,Activity的onNewIntent方法会被调用,方法原型如下:
通过此方法的参数,我们可以获取当前请求的相关信息,此时Activity的onCreate、onStart方法不会被调用,因为Activity并没有被重建
singleTask 模式
又称为栈内复用模式。这是一种单例模式,与singleTop有点类似,只不过singleTop是检测栈顶元素是否有需要启动的Activity,而singTask则是检测整个栈中是否存在当前需要启动的Activity,如果存在就直接将该Activity以上的Activity都从任务栈中移出销毁,这样该Activity就置于栈顶,同时也会回调onNewIntent方法。
当我们再次启动MainActivity时,由于MainActivity位于栈中,所以系统直接将其置于栈顶,并移除其上方的所有Activity。当然如果所需要的MainActivity不存在栈中,则会创建新的Activity并添加到栈中。singleTask 模式比较适合应用的主界面activity(频繁使用的主架构),可以用于主架构的activity,(如新闻,侧滑,应用主界面等)里面有好多fragment,一般不会被销毁,它可以跳转其它的activity 界面再回主架构界面,此时其他Activity就销毁了
singleInstance 模式
在singleInstance模式下,该Activity在整个android系统内存中有且只有一个实例,而且该实例单独尊享一个Task。换句话说,A应用需要启动的MainActivity 是singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A单独在这个新的任务栈中,如果此时B应用也要激活MainActivity,由于栈内复用的特性,则不会重新创建,而是两个应用共享一个Activity的实例
Activity启动模式的使用方式
-
通过AndroidMenifest.xml文件为Activity指定启动模式,代码如下
<activity android:name=".ActivityC"
android:launchMode="singleTask" /> -
通过在Intent中设置标志位(addFlags方法)来为Activity指定启动模式,示例代码如下:
Intent intent = new Intent();
intent.setClass(ActivityB.this,ActivityA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Intent Flag 启动模式
这里我们主要介绍一下一些常用的Activity的Flag,因为Activity的Flag比较多,我们知道一些常用的就够了,遇到比较特殊的还是查查官网文档吧。
- Intent.FLAG_ACTIVITY_NEW_TASK
该标志位表示使用一个新的Task来启动一个Activity,相当于在清单文中给Activity指定“singleTask”启
动模式。通常我们在Service启动Activity时,由于Service中并没Activity任务栈,所以必须使用该Flag
来创建一个新的Task。我们来重现一下这个错误,创建一个Service服务,并在onCreate方法中启动
- Intent.FLAG_ACTIVITY_SINGLE_TOP
该标志位表示使用singleTop模式来启动一个Activity
与在清单文件指定android:launchMode="singleTop"效果相同。
- Intent.FLAG_ACTIVITY_CLEAR_TOP
该标志位表示使用singleTask模式来启动一个Activity
与在清单文件指定android:launchMode="singleTask"效果相同。
- Intent.FLAG_ACTIVITY_NO_HISTORY
使用该模式来启动Activity,当该Activity启动其他Activity后,该Activity就被销毁了,不会保留
在任务栈中如A-B,B中以这种模式启动C,C再启动D,则任务栈只有ABD。
- Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
使用该标识位启动的Activity不添加到最近应用列表,也即我们从最近应用里面查看不到我们启动的
这个activity。与属性android:excludeFromRecents="true"效果相同。
本文摘选自: https://blog.csdn.net/javazejian/article/details/52071885
网友评论