Activity的启动模式分析-之二

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> 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值