Activity的启动模式
一、Task、栈以及加载模式
Task是一组与用户交互并执行特定工作的Activity的集合。他们根据被启动的顺序排列在栈中(回退栈)。当当前的Activity启动另一个Activty,新的Activity就会被压入栈的顶部并且得到焦点。上一个Activity仍然存在栈中,但是它停止活动了,当一个Activity停止,系统仍然会保存它的用户界面的当前状态。当用户单击“回退”按钮时,当前Activity就会从栈的顶部被弹出并且被销毁。而之前的Activity就会被恢复,栈中的Activity是不会进行重新排序的,仅仅是压入或者弹出栈。栈的管理方式是典型的“先进后出”。
其实大多数情况下,我们是没必要去关心Activity与Task是如何关联的,怎么存在于“回退栈”中的。然而,如果你想不使用Activity的默认行为,比如你希望你的应用程序在启动一个Activity时创建一个新的Task,而不是直接放入当前的Task中,或者当你启动一个Activity,你希望将已经存在在栈中的Activity带到栈的顶部,而不是在栈中创建一个新的,或者你想当用户离开Task的时候,清除栈中的所有Activity,除了根Activity。
为了达到打断默认行为的效果,我们可以自己定义启动模式(launch Mode),这里有两种方法。
一是使用manifest文件,在manifest文件中通过指定Activity的launchMode属性来定义。launchMode属性支持四种不同的值。
1、standard模式
默认模式,系统会在Task中创建新的Activity实例,并且这个Activity能被实例化多次,每个实例都能属于不同的Task,一个Task也能拥有多个实例。
2、singleTop模式
在这个模式下,如果一个Activity实例已经存在于当前Task的顶部,系统会通过调用它的onNewIntent方法发送intent请求调用已经存在于顶部的Activity实例,而不是创建一个新的Activity实例,Activity可以被实例化多次,每个实例也能属于不同的Task,一个Task也能有多个实例。(除了栈顶部的Activity实例)
例如,Task的回退栈中已经存在Activity A、B、C、D(D在顶部),当intent接受到类型D的Activity,如果D是standard模式,则会创建一个新的Activity D实例,栈中变成A、B、C、D、D。然而,如果D是singleTop模式,栈顶的D就会通过onNewIntent方法接受到intent请求,则栈中仍然是A、B、C、D。然而,如果intent接受到的是Activity B,则还是会创建一个新的B的实例到栈中,即使B也是singleTop模式。
3、singleTask模式
系统会创建一个新的Task并将Activity作为新的Task的根(root)实例化,然而,如果Activity的实例已经存在于一个其他的Task中,系统会通过onNewIntent方法发送intent请求到已经存在的实例,而不是创建一个新的实例。在同一时间,Activity的实例只能有一个。
4、singleInstance模式
跟singleTask效果一样,不同的是,系统不会加载其他的Activity到包含这个实例的Task中,Activity实例只有一个并且是Task的唯一成员,之后被该Activity启动的其他Activity都会在不同的Task中启动。
另一种打断默认行为效果的方式是通过Intent的flag。
FLAG_ACTIVITY_NEW_TASK:与singleTask效果一样。
FLAG_ACTIVITY_SINGLE_TOP:与singleTop效果一样。
FLAG_ACTIVITY_CLEAR_TOP:如果启动的Activity已经在当前Task中,那么不会再创建实例,而是所有在这个Activity实例上面的Activity都会被销毁,并通过onNewIntent方法启动该Activity。