1. Activity的启动模式
1. 什么是Task
Task是一个逻辑的概念,用来组织完成同一个功能的Activity,即使这些Activity来自不同的Application。对于用户来说, Android 通过将多个 Activity 保存在同一个 Task 里来体现这一用户体验。简单来说,一个 Task 就是用户体验上的一个“应用”。它将相关的 Activity 组合在一起,以 stack 的方式管理。也就是说stack和task是一一对应的关系,而不是stack和application是一一对应的关系。
默认情况下,新启动的Activity都和启动它的人处于同一个task中,但是Android也提供了两种方法来设置Activity加载模式,从而改变默认行为,控制task:
在Android中,每一个Activity的Task模式,都是可以由Activity提供方(通过配置文件...)和Activity使用方(通过Intent中的flag信息...)进行配置和选择。当然,使用方对Activity的控制力,是限定在提供方允许的范畴内进行,提供方明令禁止的模式,使用方是不能够越界使用的。
1. 设置manifest文件中<activity>元素的属性,这些属性包括:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
2. 设置start Activity()中Intent参数的FLAG,这些FLAG包括:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_REORDER_TO_FRONT
两种方式的差别在于,前者在于描述自己,声明自己如何被加载;而后者则是动态的,指出我要求你如何被加载。
注意:intent中FLAG的优先级比manifest中的属性值要高。
2. manifest中<activity>的launchMode属性
<activity android:name=".ActivityB"
android:label="ActivityB"
android:launchMode="">
</activity>
manifest文件中<activity>元素的launchMode属性有四个属性值:
1. "standard"(默认值)
每次启动,系统都会在启动它的task中创建一个新的实例。
是默认的也是标准的Task模式,在没有其他因素的影响下,使用此模式的Activity,会构造一个Activity的实例,加入到调用者的Task栈中去。
注意:即使Activity在当前task中被加载,但是如果该Activity属于另一个应用,系统也会创建一个新的进程,新启动的Activity也会运行在另外的进程中。所以task应该只是逻辑上的概念。
2. "singleTop"
基本上于standard一致,仅在请求的Activity正好位于栈顶时,有所区别。此时,配置成singleTop的Activity,不再会构造新的实例加入到Task栈中,而是将新来的Intent发送到栈顶Activity中,栈顶的Activity可以通过重载onNewIntent来处理新的Intent(当然,也可以无视...)。
如果Activity已经处于当前task的栈顶,则不会创建新的实例,只是调用现有实例的onNewIntent()进行更新。
Startup - launch
ActivityA:====> onCreate()
ActivityA: ====>onStart()
ActivityA:====> onPostCreate()
ActivityA:====> onResume()
ActivityA:====> onPostResume()
Start - singleTop
ActivityA:====> onPause()
ActivityA:====> onNewIntent()
ActivityA:====> onResume()
3. "singleTask"
“singleTask”的Activity只允许存在一个实例。
默认情况下,一个新启动的Activity归属于启动它的task(即使启动者所在task的taskAffinity的和SingleTask的Activity的taskAffinity值不匹配)。
当一个应用程序加载singleTask模式的Activity时,系统首先会检查是否存在与singleTask的taskAffinity相同的Task。
1. 如果task存在,检查是否实例化。
1) 如果没有实例化,实例化singleTask并入栈。
2) 如果已经实例化,销毁在singleTask以上的所有Activity并调用onNewIntent()。
2. 如果task不存在,那么就重新创建Task,并实例化singleTask入栈。
1. Start singleTask activity within same task
======================================== ======================================
Startup - launch
ActivityA: ====> onCreate()
ActivityA: ====> onStart()
ActivityA: ====> onPostCreate()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
Activity A ==> Activity B(singleTask)
ActivityA: ====> onSaveInstanceState()
ActivityA: ====> onPause()
ActivityB: ====> onCreate()
ActivityB: ====> onStart()
ActivityB: ====> onPostCreate()
ActivityB: ====> onResume()
ActivityB: ====> onPostResume()
ActivityA: ====> onStop()
Activity B(singleTask) ==> Activity B(singleTask)
ActivityB:====> onPause()
ActivityB:====> onNewIntent()
ActivityB:====> onResume()
Back
ActivityB: ====> onPause()
ActivityA: ====> onRestart()
ActivityA: ====> onStart()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
ActivityB: ====> onStop()
ActivityB: ====> onDestroy()
Back(exit)
ActivityA: ====> onPause()
ActivityA: ====> onStop()
ActivityA: ====> onDestroy()
===============================================================================
可以看到,当在自身应用中启动singleTask时,系统并没有创建一个新的task,而是在原来的task中创建了singleTask。这是因为同一个应用中的Activity默认是共享同一个taskAffinity值的,所以当系统检索到singleTask所归属的task已经存在,就直接在该task中创建它了。
2. Start existing singleTask activity within same task
Startup - launch
ActivityA: ====> onCreate()
ActivityA: ====> onStart()
ActivityA: ====> onPostCreate()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
Activity A ==> Activity B(singleTask)
ActivityA: ====> onSaveInstanceState()
ActivityA: ====> onPause()
ActivityB: ====> onCreate()
ActivityB: ====> onStart()
ActivityB: ====> onPostCreate()
ActivityB: ====> onResume()
ActivityB: ====> onPostResume()
ActivityA: ====> onStop()
Activity B(singleTask) ==> Activity C
ActivityB: ====> onSaveInstanceState()
ActivityB: ====> onPause()
ActivityC: ====> onCreate()
ActivityC: ====> onStart()
ActivityC: ====> onPostCreate()
ActivityC: ====> onResume()
ActivityC: ====> onPostResume()
ActivityB: ====> onStop()
Activity C ==> Activity D
ActivityC: ====> onSaveInstanceState()
ActivityC: ====> onPause()
ActivityD: ====> onCreate()
ActivityD: ====> onStart()
ActivityD: ====> onPostCreate()
ActivityD: ====> onResume()
ActivityD: ====> onPostResume()
ActivityC: ====> onStop()
Activity D ==> Activity B(singleTask)
ActivityC: ====> onDestroy()
ActivityD:====> onPause()
ActivityB:====> onNewIntent()
ActivityB: ====> onRestart()
ActivityB: ====> onStart()
ActivityB: ====> onResume()
ActivityB: ====> onPostResume()
ActivityD: ====> onStop()
ActivityD: ====> onDestroy()
Back
ActivityB: ====> onPause()
ActivityA: ====> onRestart()
ActivityA: ====> onStart()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
ActivityB: ====> onStop()
ActivityB: ====> onDestroy()
Back(exit)
ActivityA: ====> onPause()
ActivityA: ====> onStop()
ActivityA: ====> onDestroy()
===============================================================================
可以看到,当singleTask启动时,如果发现它在堆栈中已经存在,那么系统首先会destory堆栈中位于singleTask之上所有Activity(除了栈顶的Activity,也就是启动者),然后在启动者(也就是栈顶Activity)和singleTask之间做类似于back的操作,但是会调用singleTask的onNewIntent()函数。
3. Start singleTask activity from TestApp – case A
假设singleTask所属的task(App)没有运行,此时通过TestApp启动singleTask:
==============================================================================
==> TestApp Startup
ActivityA(TestApp): ====> onCreate()
ActivityA(TestApp):TaskId=74
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onPostCreate()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
==> Activity B(singleTask)
ActivityA(TestApp): ====> onPause()
ActivityB(App): ====> onCreate()
ActivityB(App):TaskId=75
ActivityB(App): ====> onStart()
ActivityB(App): ====> onPostCreate()
ActivityB(App): ====> onResume()
ActivityB(App): ====> onPostResume()
ActivityA(TestApp): ====> onStop()
Back
ActivityB(App): ====> onPause()
ActivityA(TestApp): ====> onRestart()
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
ActivityB(App): ====> onStop()
ActivityB(App): ====> onDestroy()
ActivityB(App):TaskId=75
Back(exit)
ActivityA(TestApp): ====> onPause()
ActivityA(TestApp): ====> onStop()
ActivityA(TestApp): ====> onDestroy()
ActivityA(TestApp):TaskId=74
===============================================================================
可以看出,启动singleTask时,系统创建了一个新的task。
4. Start singleTask activity from TestApp – case B
假设singleTask所属的task(App)已经运行,但是singleTask却还没有被启动(也就是说还没有存在Activity堆栈中),此时通过TestApp启动singleTask:
==============================================================================
==> App Startup
ActivityA(App): ====> onCreate()
ActivityA(App):TaskId=93
ActivityA(App): ====> onStart()
ActivityA(App): ====> onPostCreate()
ActivityA(App): ====> onResume()
ActivityA(App): ====> onPostResume()
==> TestApp Startup
ActivityA(TestApp): ====> onCreate()
ActivityA(TestApp):TaskId=94
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onPostCreate()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
==> Activity B(singleTask)
ActivityA(TestApp): ====> onPause()
ActivityB(App): ====> onCreate()
ActivityB(App):TaskId=93
ActivityB(App): ====> onStart()
ActivityB(App): ====> onPostCreate()
ActivityB(App): ====> onResume()
ActivityB(App): ====> onPostResume()
ActivityA(TestApp): ====> onStop()
Back
ActivityB(App): ====> onPause()
ActivityA(App): ====> onRestart()
ActivityA(App): ====> onStart()
ActivityA(App): ====> onResume()
ActivityA(App): ====> onPostResume()
ActivityB(App): ====> onStop()
ActivityB(App): ====> onDestroy()
ActivityB(App):TaskId=93
Back
ActivityA(App): ====> onPause()
ActivityA(TestApp): ====> onRestart()
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
ActivityA(App): ====> onStop()
ActivityA(App): ====> onDestroy()
ActivityA(App):TaskId=93
Back(exit)
ActivityA(TestApp): ====> onPause()
ActivityA(TestApp): ====> onStop()
ActivityA(TestApp): ====> onDestroy()
ActivityA(TestApp):TaskId=94
===============================================================================
可以看出,系统会检测到singleTask所属的task(App),并在该task中启动singleTask。
5. Start singleTask activity from TestApp – case C
假设singleTask所属的task(App)已经运行,而且刚好singleTask处于栈顶,此时通过TestApp启动singleTask:
==============================================================================
==> App Startup
ActivityA(App): ====> onCreate()
ActivityA(App):TaskId=95
ActivityA(App): ====> onStart()
ActivityA(App): ====> onPostCreate()
ActivityA(App): ====> onResume()
ActivityA(App): ====> onPostResume()
Activity A ==> Activity B(singleTask)
ActivityA(App): ====>onSaveInstanceState()
ActivityA(App): ====> onPause()
ActivityB(App): ====> onCreate()
ActivityB(App):TaskId=95
ActivityB(App): ====> onStart()
ActivityB(App): ====> onPostCreate()
ActivityB(App): ====> onResume()
ActivityB(App): ====> onPostResume()
ActivityA(App): ====> onStop()
==> TestApp Startup
ActivityA(TestApp): ====> onCreate()
ActivityA(TestApp):TaskId=96
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onPostCreate()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
==> Activity B(singleTask)
ActivityA(TestApp): ====> onPause()
ActivityB(App):====> onNewIntent()
ActivityB(App):TaskId=95
ActivityB(App): ====> onRestart()
ActivityB(App): ====> onStart()
ActivityB(App): ====> onResume()
ActivityB(App): ====> onPostResume()
ActivityA(TestApp): ====> onStop()
Back
ActivityB(App): ====> onPause()
ActivityA(App): ====> onRestart()
ActivityA(App): ====> onStart()
ActivityA(App): ====> onResume()
ActivityA(App): ====> onPostResume()
ActivityB(App): ====> onStop()
ActivityB(App): ====> onDestroy()
ActivityB(App):TaskId=95
Back
ActivityA(App): ====> onPause()
ActivityA(TestApp): ====> onRestart()
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
ActivityA(App): ====> onStop()
ActivityA(App): ====> onDestroy()
ActivityA(App):TaskId=95
Back(exit)
ActivityA(TestApp): ====> onPause()
ActivityA(TestApp): ====> onStop()
ActivityA(TestApp): ====> onDestroy()
ActivityA(TestApp):TaskId=96
===============================================================================
可以看出,系统会检测到singleTask所属的task(App),并且发现singleTask处于栈顶,于是就调用singleTask的onNewIntent()函数。
6. Start singleTask activity from TestApp – case D
假设singleTask所属的task(App)已经启动,而且singleTask已经位于栈内,但是现在栈顶的是ActivityD。此时通过TestApp启动singleTask:
==============================================================================
==> TestApp Startup
ActivityA(TestApp): ====> onCreate()
ActivityA(TestApp):TaskId=74
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onPostCreate()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
==> Activity B(singleTask)
ActivityA(TestApp): ====> onPause()
ActivityC(App): ====> onDestroy()
ActivityD(App): ====> onDestroy()
ActivityB(App):====> onNewIntent()
ActivityB(App):TaskId=70
ActivityB(App): ====> onRestart()
ActivityB(App): ====> onStart()
ActivityB(App): ====> onResume()
ActivityB(App): ====> onPostResume()
ActivityA(TestApp): ====> onStop()
Back
ActivityB(App): ====> onPause()
ActivityA(App): ====> onRestart()
ActivityA(App): ====> onStart()
ActivityA(App): ====> onResume()
ActivityA(App): ====> onPostResume()
ActivityB(App): ====> onStop()
ActivityB(App): ====> onDestroy()
ActivityB(App):TaskId=70
Back
ActivityA(App): ====> onPause()
ActivityA(TestApp): ====> onRestart()
ActivityA(TestApp): ====> onStart()
ActivityA(TestApp): ====> onResume()
ActivityA(TestApp): ====> onPostResume()
ActivityA(App): ====> onStop()
ActivityA(App): ====> onDestroy()
ActivityA(App):TaskId=70
Back(exit)
ActivityA(TestApp): ====> onPause()
ActivityA(TestApp): ====> onStop()
ActivityA(TestApp): ====> onDestroy()
ActivityA(TestApp):TaskId=74
===============================================================================
可以看出,系统首先会按照顺序依次destroy堆栈中位于singleTask之上的所有Activity。然后调用singleTask的onNewIntent()函数。
当用户点击back时,必须首先将singleTask所属的task(App)的堆栈back清空,才能back回到最初的task(TestApp),也就是说Activity的堆栈是和task绑定的。
4. "singleInstance"
和"singleTask"一样,“singleInstance”的Activity只允许存在一个实例,但是"singleInstance"是所属task中的唯一activity,所有由singleInstance所启动的activity都会被放置到另外的task中启动。
所以,可以看出,与"singleTask"不同的是,当在自身应用中启动singleInstance时,系统会创建一个新的task。而启动singleTask时,系统不会创建新的task,这是因为singleInstance在task中必须是唯一的。
当应用程序加载一个singleInstance模式的Activity时,如果没有被实例化,那么就重新创建一个Task,并实例化入栈,如果已经被实例化,那么就将singleInstance所在的task带到前台,并调用singleInstance的onNewIntent()。
1. Start singleInstance activity within same app
==============================================================================
Startup - launch
ActivityA: ====> onCreate()
ActivityA:TaskId=76
ActivityA: ====> onStart()
ActivityA: ====> onPostCreate()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
Activity A ==> Activity B(singleInstance)
ActivityA: ====> onSaveInstanceState()
ActivityA: ====> onPause()
ActivityB: ====> onCreate()
ActivityB:TaskId=77
ActivityB: ====> onStart()
ActivityB: ====> onPostCreate()
ActivityB: ====> onResume()
ActivityB: ====> onPostResume()
ActivityA: ====> onStop()
Activity B(singleInstance) ==> Activity C
ActivityB: ====> onSaveInstanceState()
ActivityB: ====> onPause()
ActivityC: ====> onCreate()
ActivityC:TaskId=76
ActivityC: ====> onStart()
ActivityC: ====> onPostCreate()
ActivityC: ====> onResume()
ActivityC: ====> onPostResume()
ActivityB: ====> onStop()
Back – note: back toActivity A instead of Activity B(singleInstance)
ActivityC: ====> onPause()
ActivityA: ====> onRestart()
ActivityA: ====> onStart()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
ActivityC: ====> onStop()
ActivityC: ====> onDestroy()
ActivityC:TaskId=76
Back – back from Activity Ato Activity B(singleInstance)
ActivityA: ====> onPause()
ActivityB: ====> onRestart()
ActivityB: ====> onStart()
ActivityB: ====> onResume()
ActivityB: ====> onPostResume()
ActivityA: ====> onStop()
ActivityA: ====> onDestroy()
ActivityA:TaskId=76
Back(exit)
ActivityB: ====> onPause()
ActivityB: ====> onStop()
ActivityB: ====> onDestroy()
ActivityB:TaskId=77
==============================================================================
当应用程序加载一个singleInstance模式的Activity时,如果没有被实例化,那么就重新创建一个Task,并实例化入栈,
可以看出,当启动singleInstance时,即使是在自身的应用里面,也会创建一个新的task来加载singleInstance的Activity。需要注意的是,之后启动的Activity仍然会被加载到原有应用的task中。
2. Start existing singleInstance activity within same app
当应用程序加载一个singleInstance模式的Activity时,如果已经被实例化,那么就将singleInstance所在的task带到前台,并调用singleInstance的onNewIntent()。
3. Start singleInstance activity within other app
当应用程序加载一个singleInstance模式的Activity时,如果没有被实例化,那么就重新创建一个Task,并实例化入栈,
4. Start existing singleInstance activity within other app
当应用程序加载一个singleInstance模式的Activity时,如果已经被实例化,那么就将singleInstance所在的task带到前台,并调用singleInstance的onNewIntent()。
1. 四种加载模式的区别
1. 归属task的区别:
“standard”和“singleTop”和启动者处在同一个task内,就相当于谁启动了它,它就跟谁在同一个Task中。
“singleTask”如果是在自身的应用中被启动,就归属于自身的task,如果被其它的应用(task)启动,就会被启动到自身应用的task。
“singleInstance”总是会启动到它自己的task里。
2. 是否允许多个实例
“standard”和“singleTop”可以被实例化多次,既可以存在于同一个task中;也可以存在于不同的task中。
“singleTask”和“singleInstance”则限制只生成一个实例。
2. 避免孤岛task
“singleTask”和“singleInstance”可能会导致孤岛task。例如:
1. 启动一个应用A(taskA);
2. 在A中启动了“singleTask”或“singleInstance”,系统会生成一个新的taskB;
3. 按Home键切回主屏,进行其它操作;
4. 再通过快捷方式返回应用A(taskA),发现已经不是处于“singleTask”或“singleInstance”的activity;
5. 此时的“singleTask”或“singleInstance”已经是孤岛task,用户再也无法访问它们。
所以,为避免孤岛task,一般要求“singleTask”或“singleInstance”的activity必须具有“LAUNCHER”的属性。这样用户就可以通过应用图标访问它们。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>