一个Android应用程序功能一般会有许多Activity组成,每个Activity之间都是通过Intent进行连接,因此一个App会包含许多的Activity,而在Android系统中,是通过栈结构来保存整个App的Activity,栈底的元素是整个任务栈的发起者。一个合理的任务调度栈不仅是性能的保证,更是提供性能的基础。
如果读者还不了解Activity的生命周期,可以先阅读这篇文章http://blog.csdn.net/dzh_19950513/article/details/52192116。
当一个App启动时。如果当前环境中不存在该App的任务栈。那么系统就会创建一个任务栈。此后,这个App所启动的Activity都将在这个任务栈中被管理,这个栈也被称为一个Task,即表示若干个Activity的集合,他们组合在一个就形成一个Task。另外需要注意的是,一个Task中的Activity可以来自不同的APP,同一个APP的Activity可以在不同的Task中。一般来说当一个Activity1启动Activity2的时候,这个时候Activity2就会变成栈顶元素,就会显示在前台界面处于Running状态,而Activity1如果没有finish那么Activity1就会保留在任务栈中,处于Stopped状态,当用户按下返回键或者finish掉了,那么就会移除栈顶的Activity,让后面的Activity处于活动状态。当然,也可以通过设置Activity的启动模式来打破这种规律。
开发者可用在AndroidMainifest文件中和Intent的Flag设置Activity的启动模式,Activity的启动模式,分别有如下四种:
☆ standard
☆ singleTop
☆ singleTask
☆ singleInstance
1. standard
默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加,例如A启动A,A再接着启动A,A继续启动A,然后再分别出栈,如图所示;
2. singleTop
可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。
例如:当A在栈顶时,若一直创建A,则不会再栈顶上再次创建A,如下图。
3. singleTask
☆ 只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
4. singleInstance
只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。例如,手机上的浏览器就是采用了这个模式,如果当前浏览器没有打开,则在另外一个Task中打开浏览器,如果已经打开了则直接跳转过去不再创建。
Intent Flag启动模式:
☆ Intent.FLAG_ACTIVITY_NEW_TASK (默认)
默认的跳转类型,它会重新创建一个新的Activity,不过与这种情况,比如说Task1中有A,B,C三个Activity,此时在C中启动D的话,如果在AndroidManifest.xml文件中给D添加了Affinity的值和Task中的不一样的话,则会在新标记的Affinity所存在的Task中压入这个Activity。如果是默认的或者指定的Affinity和Task一样的话,就和标准模式一样了启动一个新的Activity.
☆ FLAG_ACTIVITY_SINGLE_TOP
这个FLAG就相当于启动模式中的singletop,例如:原来栈中结构是A B C D,在D中启动D,栈中的情况还是A,B,C,D。☆ FLAG_ACTIVITY_CLEAR_TOP
这个FLAG就相当于启动模式中的SingleTask,这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。例如:原来栈中的结构是A B C D ,从D中跳转到B,栈中的结构就变为了A B了。(这个方法可以用来关闭多个Activity,之后的一篇博文里面会提到)
☆ FLAG_ACTIVITY_BROUGHT_TO_FRONT
这个FLAG就相当于启动模式中的SsingleInstance,比如说我现在有A,在A中启动B,此时在A中Intent中加上这个标记。此时B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式启动,此时在B中再启动C,D(正常启动C,D),这个时候最后的栈的情况是 A,C,D。
清空任务栈:可以在AndroidMainifest文件的<actviity>使用一下几种属性来清理任务栈。
☆ clearTaskOnLaunch
☆ finishOnTaskLaunch
☆ alwaysRetainTaskState
1. clearTaskOnLaunch
通过这个属性,就是每次返回这个Activity时都将该Activity之上的所有Activity都清除,通过这个属性,可以让这个Task每次在初始化的时候,都只有这一个Activity。
2. finishOnTaskLaunch
通过这个属性,当用户离开这个Task时,那么用户再返回,该Activity就会被finish掉。
3. alwaysRetainTaskState
通过这个属性,相当于给了该Activity一道"免死金牌",那么该Activity将不接受任何的清理任务,一直保持着当前的Task状态。
Activity栈的使用:合理的使用Activity的启动模式会让程序运行更有效率,用户体验更好,但如果过度的使用Activity任务栈,则会导致整个App的栈管理混乱,不仅不利于以后程序的扩展,而且在容易出现任务栈导致的显示异常。所有,在App中使用Activity任务栈一定要根据实际项目的需要,而不是为了使用任务栈而使用任务栈。
参考资料:http://www.androidchina.net/3173.html