在android应用开发中,打造良好的用户体验是很重要的。而在用户体验中,界面的引导和跳转是值得深入研究的内容。在开发中,与界面跳转联系比较紧密的概念是“Task”和“Back Stack”回退栈。Activity的启动模式和Intent类中定义的一些标志会影响task和back stack的状态,进而影响用户体验。
一、基础概念
task
task是一个“First In Last Out”的栈,task中可以有一个或者多个Activity。task可以看作是管理Activity的单元,系统中可能存在一个或者多个task,每个task里面有一个或者多个Activity。对于一个Activity,可能只容许有一个实例或者可以有多个实例,这些实例可能位于多个Task,也可能位于一个task中。
Activity如何处理它的实例,以及它在task中的分布情况,这些可以通过launchMode/相关Flags来进行控制。
taskAffinity
Activity的一个属性,值为string,用于描述Activity之间的亲密关系。
如果Activities拥有同样的taskAffinity,则它们是亲密的,它们之间在相互跳转时会位于同一个Task中,并不会产生新的task。反之情况比较复杂。
默认情况下,每个Activity都采用和Application相同的taskAffinity,如果Application没有设置的话,则默认使用包名。
二、启动模式
包括四种启动模式:standard、singleTop、singleTask、singleInstance
standard
默认模式。在该模式下,Activity可拥有多个实例,并且每次启动新添加一个实例,并且这些实例既可以位于同一个task,也可以位于不同的task(依据启动它的Activity模式和当前task)。
singleTop
singleTop模式下,在同一个task中,如果存在Activity的实例并且该实例位于栈顶,则调用startActivity()时不再重新创建一个实例,而是调用该Activity的onNewIntent方法。
singleTask
总结:只容许有一个包含该Activity实例的task存在。
singleTask官方介绍中有三个特点:
1.如果是第一次创建该Activity实例,则新建task并将该Activity添加到该task中。
2.如果已经存在该Activity实例,则打开已有的Activity实例,并且调用Activity的onNewIntent()方法,并不会创建新的Activity实例。
3.在任一时刻,最多只有一个该Activity实例存在
在实际测试中,发现singleTask的表现与taskAffinity属性设置相关。
在taskAffinity属性相同时,第一次创建Activity实例时,并不会启动新的task,而是直接添加到原有task。非第一次启动,将Activity所在task中Activity之上的全部Activity删除,然后跳转到该Activity中。
在taskAffinity属性不相同时,第一次创建Activity实例时,会启动新的task,并将实例添加到新创建的task中。非第一次启动,将Activity所在task中Activity之上的全部Activity删除,然后跳转到该Activity中。
singleInstance
总结:只容许存在唯一的Activity实例。
singleInstance官方介绍中有两个特点:
1.如果是第一次创建该activity实例,则新建task并将该Activity添加到task中,并且该task中只能容纳该Activity这一个实例,不会再添加其他Activity实例。
2.如果该Activity实例已经存在于某个task中,则直接跳转到该task。
singleTask和singleInstance有相同之处,也有不同之处。
相同之处:任意时刻,最多只容许存在一个实例。
不同之处:
1.singleTask受android:taskAffinity属性的影响,singleInstance不受android:taskAffinity的影响。
2.singleTask模式下,实例所在栈中容许有其他Activity实例,singleInstance模式下,实例所在栈不容许有其他实例存在。
3.当跳转到Activity实例时,singleTask会删除task中位于实例之上的所有Activity,singleInstance中不需要删除。
三、Intent与启动模式相关Flag
包括四个相关flag,FLAG_ACTIVITY_NEW_TASK,FLAG_ACTIVITY_CLEAR_TASK,FLAG_ACTIVITY_CLEAR_TOP,FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_SINGLE_TOP
作用和singleTop一样,调用startActivity时,如果同一个task中已经存在了Activity的实例并且改实例位于栈顶,则不创建新的Activity实例,直接调用Activity的onNewIntent方法。否则创建一个新的Activity实例并压入栈中。
FLAG_ACTIVITY_NEW_TASK
官方说明上和singleTask具有相同的效果,但是在实际使用过程中并不是如此,一般和FLAG_ACTIVITY_CLEAR_TASK/FLAG_ACTIVITY_CLEAR_TOP搭配使用。
在taskAffinity相同时,FLAG_ACTIVITY_NEW_TASK并不起作用,表现和standerd相同。
在taskAffinity不相同时,第一次启动Activity时会创建一个新的task,并将该实例添加到task中,非第一次启动Activity,则不会发生任何事。
FLAG_ACTIVITY_CLEAR_TOP
当taskAffinity相同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TOP没有任何作用。和没有添加时的效果一样。
当taskAffinity不同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TOP后,表现的和singleTask一样。
FLAG_ACTIVITY_CLEAR_TASK
当taskAffinity相同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TASK没有任何作用。和没有添加时的效果一样。
当taskAffinity不同时:添加FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TASK后,启动Activity,如果Activity已有实例存在,则情况该task并创建一个Activity实例压入改task中。否则,直接启动新的task并将B添加到新建的task中。
四、启动模式的其它属性
包括:
- android:taskAffinity
- allowTaskReparenting
- alwaysRetainTaskState
- clearTaskOnLaunch
- finishOnTaskLaunch
仅做了解