锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

【Android 12】Activity启动模式

时间:2023-10-17 20:07:01 t236集成电路

一、启动模式

google文档介绍:

可以通过启动模式定义 Activity 如何与现在相匹配新的例子Task关联。您可以通过两种方式定义不同的启动模式:

使用manifest文件

当您在manifest文件中声明 Activity 当时,你可以指定 Activity 启动时如何与之相处Task关联。

使用Intent标记

当您调用 startActivity(),可以在 Intent在声明中添加一个新的标记 Activity 如何(或是否)和现在Task相关联。

因此,如果 Activity A 启动 Activity B,Activity B 可在其manifest如何定义与当下Task相关关联(如果相关),Activity A 也可以请求 Activity B 该如何与现在相匹配Task关联。如果两个 Activity 都定义了 Activity B 应如何与Task优先关联 Activity A 的请求(在 intent 中定义),而不是 Activity B 的请求(在manifest中定义)。

注:可以使用一些启动模式manifest文件定义,但不能通过 intent 同样,一些启动模式也可以通过标记定义 intent 标记定义,但不能manifest中定义。

二、使用manifest文件

在manifest文件中声明 Activity 可使用元素launchMode属性指定 Activity 应该如何与Task关联。

launchMode属性说明了Activity 如何启动?Task中。launchMode定义如下:

                             

launMode有5种:

standard、singleTop、singleTask、singleInstance、singleInstancePerTask。

如果launchMode如果属性没有指定,则默认为standard模式。操作时注意特殊启动模式。Intent的flag改变。

1 standard

1.1 standard定义

         

1)、渣翻:

通常在默认模式下Activity创建一个新的例子,尽管这种行为可能会随着其他选项的引入而改变,例如Intent.FLAG_ACTIVITY_NEW_TASK。

2)、google文档定义:

“standard(默认模式)

默认值。该系统正在启动 Activity 的任务中创建 Activity 并将新实例 intent 传递给这个例子。Activity 可以多次实例化,每个实例可以属于不同的任务,一个任务可以有多个实例。

1.2 standard实际应用

新建一个launchMode声明为standard的Activity,StandardActivity。

以MainActivity起点,启动StandardActivity,堆栈情况如下:

 #6 Task=83 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]          #1 ActivityRecord{9aefb8a u0 com.test.la un ch mo de/.StandardActivity t83} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]          #0 ActivityRecord{3c3ba3c u0 com.test.la un ch mo de/.MainActivity t83} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]  

试着重新开始StandardActivity一个新的例子,堆栈的结果如下:

 #6 Task=83 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]          #2 ActivityRecord{9542c1 u0 com.test.la un ch mo de/.StandardActivity t83} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]          #1 ActivityRecord{9aefb8a u0 com.test.la un ch mo de/.StandardActivity t83} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]          #0 ActivityRecord{3c3ba3c u0 com.test.la un ch mo de/.MainActivity t83} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]  

image-20220304160230323.png

StandardActivity例子可以多次创建,所以一个StandardActivity的新实例StandardActivity创建并位于当前Task的top。

2 singleTo

2.1 singleTop定义

 
      

1)、渣翻:

当启动Activity时,在前台已经有一个与用户交互的相同Activity的实例,那么重用该实例。这个已经存在的实例将收到一个对Activity.onNewIntent()}的调用,传参是正在启动的Intent。

2)、google文档定义:

“singleTop”

如果当前任务的顶部已存在 Activity 的实例,则系统会通过调用其onNewIntent()方法来将 intent 转送给该实例,而不是创建 Activity 的新实例。Activity 可以多次实例化,每个实例可以属于不同的任务,一个任务可以拥有多个实例(但前提是返回堆栈顶部的 Activity 不是该 Activity 的现有实例)。

例如,假设任务的返回堆栈包含根 Activity A 以及 Activity B、C 和位于顶部的 D(堆栈为 A-B-C-D;D 位于顶部)。收到以 D 类型 Activity 为目标的 intent。如果 D 采用默认的 “standard” 启动模式,则会启动该类的新实例,并且堆栈将变为 A-B-C-D-D。但是,如果 D 的启动模式为 “singleTop”,则 D 的现有实例会通过onNewIntent()接收 intent,因为它位于堆栈顶部,堆栈仍为 A-B-C-D。但是,如果收到以 B 类型 Activity 为目标的 intent,则会在堆栈中添加 B 的新实例,即使其启动模式为 “singleTop” 也是如此。

注意:创建 Activity 的新实例后,用户可以按返回按钮返回到上一个 Activity。但是,当由 Activity 的现有实例处理新 intent 时,用户将无法通过按返回按钮返回到onNewIntent()收到新 intent 之前的 Activity 状态。

2.2 singleTop实际应用

新建一个launchMode声明为singleTop的Activity,SingleTopActivity。

2.2.1 SingleTopActivity的实例已经处于Task top的情况下启动SingleTopActivity

以MainActivity为起点,启动SingleTopActivity:

 #6 Task=85 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{3373d6a u0 com.test.launchmode/.SingleTopActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{d66e925 u0 com.test.launchmode/.MainActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

此时再次尝试启动SingleTopActivity:

由于此时已经有一个SingleTopActivity的实例位于Task的top,因此不会启动一个新的SingleTopActivity,而是处于Task top的这个SingleTopActivity实例收到Activity.onNewIntent回调:

03-01 15:15:45.995  1483  6147 I wm_new_intent: [0,222456063,86,com.test.launchmode/.SingleTopActivity,NULL,NULL,NULL,0]
03-01 15:15:46.028  9926  9926 I wm_on_top_resumed_lost_called: [222456063,com.test.launchmode.SingleTopActivity,pausing]
03-01 15:15:46.029  9926  9926 I wm_on_paused_called: [222456063,com.test.launchmode.SingleTopActivity,performPause]
03-01 15:15:46.029  9926  9926 I launchmode_test: SingleTopActivity#onNewIntent
03-01 15:15:46.030  9926  9926 I wm_on_resume_called: [222456063,com.test.launchmode.SingleTopActivity,LIFECYCLER_RESUME_ACTIVITY]
03-01 15:15:46.030  9926  9926 I wm_on_top_resumed_gained_called: [222456063,com.test.launchmode.SingleTopActivity,topWhenResuming] 

2.2.2 SingleTopActivity的实例没有处于Task top的情况下启动SingleTopActivity

接2.2.1,此时再启动一个StandardActivity:

 #6 Task=85 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #2 ActivityRecord{7b9e87a u0 com.test.launchmode/.StandardActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{3373d6a u0 com.test.launchmode/.SingleTopActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{d66e925 u0 com.test.launchmode/.MainActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

最后在SingleTopActivity不为top的情况再次尝试启动SingleTopActivity:

 #6 Task=85 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #3 ActivityRecord{655dbef u0 com.test.launchmode/.SingleTopActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #2 ActivityRecord{7b9e87a u0 com.test.launchmode/.StandardActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{3373d6a u0 com.test.launchmode/.SingleTopActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{d66e925 u0 com.test.launchmode/.MainActivity t85} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

这时由于之前启动的SingleTopActivity的实例SingleTopActivity1没有位于top,所以这次会创建一个SingleTopActivity的新实例SingleTopActivity2。

3 singleTask

3.1 singleTask定义

 
         

1)、渣翻:

当启动该Activity的时候,如果已经有一个正在运行的Task以该Activity启动,那么该Task将被移动到前台,而不是启动一个新的实例。现存的实例将会收到Activity.onNewIntent()方法的调用,传入正在启动的Intent,这个Intent还会被设置Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT。这是singleTop模式的超集。

2)、google文档:

“singleTask”

系统会创建新任务,并实例化新任务的根 Activity。但是,如果另外的任务中已存在该 Activity 的实例,则系统会通过调用其onNewIntent()方法将 intent 转送到该现有实例,而不是创建新实例。Activity 一次只能有一个实例存在。

注意:虽然 Activity 在新任务中启动,但用户按返回按钮仍会返回到上一个 Activity。

再举个例子,Android 浏览器应用在元素中指定 singleTask 启动模式,由此声明网络浏览器 Activity 应始终在它自己的任务中打开。这意味着,如果您的应用发出打开 Android 浏览器的 intent,系统不会将其 Activity 置于您的应用所在的任务中,而是会为浏览器启动一个新任务,如果浏览器已经有任务在后台运行,则会将该任务转到前台来处理新 intent。

无论 Activity 是在新任务中启动的,还是在和启动它的 Activity 相同的任务中启动,用户按返回按钮都会回到上一个 Activity。但是,如果您启动了指定 singleTask 启动模式的 Activity,而后台任务中已存在该 Activity 的实例,则系统会将该后台任务整个转到前台运行。此时,返回堆栈包含了转到前台的任务中的所有 Activity,这些 Activity 都位于堆栈的顶部。图 4 展示了具体的情景。

图 4. 采用“singleTask”启动模式的 Activity 添加到返回堆栈的过程图示。如果 Activity 已经存在于某个具有自己的返回堆栈的后台任务中,那么整个返回堆栈也会转到前台,覆盖当前任务。

要详细了解如何在清单文件中设置启动模式,请参阅元素的说明文档,里面详细介绍了 launchMode 属性和可接受的值。

注意:您通过launchMode属性为 Activity 指定的行为,可被启动 Activity 的 intent 所包含的标记替换。

3.2 singleTask实际应用

新建一个launchMode声明为singleTask的Activity,SingleTaskActivity。

3.2.1 启动SingleTaskActivity

以MainActivity为起点:

 #6 Task=100 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{14b21d2 u0 com.test.launchmode/.MainActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

启动SingleTaskActivity:

 #6 Task=100 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{f14ffea u0 com.test.launchmode/.SingleTaskActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{14b21d2 u0 com.test.launchmode/.MainActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

新实例仍然在Task#100中,并没有想象中那样为SingleTaskActivity创建一个新的Task。

3.2.2 SingleTaskActivity已经处于当前Task的top的情况下启动SingleTaskActivity

接3.2.1,此时再次尝试启动SingleTaskActivity:

由于此时已经有一个SingleTaskActivity的实例位于Task的top,因此不会启动一个新的SingleTaskActivity,而是处于Task top的这个SingleTaskActivity实例收到Activity.onNewIntent回调:

03-01 17:50:11.789  1483  6167 I wm_new_intent: [0,253034474,100,com.test.launchmode/.SingleTaskActivity,NULL,NULL,NULL,268435456]
03-01 17:50:11.791  1483  6167 I wm_task_moved: [100,1,6]
03-01 17:50:11.796  1483  6167 I wm_set_resumed_activity: [0,com.test.launchmode/.SingleTaskActivity,positionChildAt]
03-01 17:50:11.842 15874 15874 I wm_on_top_resumed_lost_called: [253034474,com.test.launchmode.SingleTaskActivity,pausing]
03-01 17:50:11.843 15874 15874 I wm_on_paused_called: [253034474,com.test.launchmode.SingleTaskActivity,performPause]
03-01 17:50:11.843 15874 15874 I launchmode_test: SingleTaskActivity#onNewIntent
03-01 17:50:11.844 15874 15874 I wm_on_resume_called: [253034474,com.test.launchmode.SingleTaskActivity,LIFECYCLER_RESUME_ACTIVITY]
03-01 17:50:11.845 15874 15874 I wm_on_top_resumed_gained_called: [253034474,com.test.launchmode.SingleTaskActivity,topWhenResuming] 

3.2.3 SingleTaskActivity没有处于当前Task的top的情况下启动SingleTaskActivity

接3.2.2,启动一个StandardActivity:

 #6 Task=100 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #2 ActivityRecord{c901e6c u0 com.test.launchmode/.StandardActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{f14ffea u0 com.test.launchmode/.SingleTaskActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{14b21d2 u0 com.test.launchmode/.MainActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

然后再尝试启动SingleTaskActivity:

 #6 Task=100 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{f14ffea u0 com.test.launchmode/.SingleTaskActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{14b21d2 u0 com.test.launchmode/.MainActivity t100} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

之前启动的StandardActivity被销毁,SingleTaskActivity没有被重新创建,而是旧的实例收到Activity.onNewIntent回调。

03-01 17:52:13.212  1483  1500 I wm_finish_activity: [0,210771564,100,com.test.launchmode/.StandardActivity,clear-task-stack]
03-01 17:52:13.217  1483  1500 I wm_pause_activity: [0,210771564,com.test.launchmode/.StandardActivity,userLeaving=false,finish]
03-01 17:52:13.221  1483  1500 I wm_new_intent: [0,253034474,100,com.test.launchmode/.SingleTaskActivity,NULL,NULL,NULL,268435456]
03-01 17:52:13.222  1483  1500 I wm_task_moved: [100,1,6]
03-01 17:52:13.310 15874 15874 I wm_on_top_resumed_lost_called: [210771564,com.test.launchmode.StandardActivity,topStateChangedWhenResumed]
03-01 17:52:13.325 15874 15874 I wm_on_paused_called: [210771564,com.test.launchmode.StandardActivity,performPause]
03-01 17:52:13.330  1483  9284 I wm_add_to_stopping: [0,210771564,com.test.launchmode/.StandardActivity,completeFinishing]
03-01 17:52:13.379  1483  9284 I wm_set_resumed_activity: [0,com.test.launchmode/.SingleTaskActivity,resumeTopActivityInnerLocked]
03-01 17:52:13.470  1483  9284 I wm_resume_activity: [0,253034474,100,com.test.launchmode/.SingleTaskActivity]
03-01 17:52:13.577 15874 15874 I wm_on_restart_called: [253034474,com.test.launchmode.SingleTaskActivity,performRestartActivity]
03-01 17:52:13.577 15874 15874 I wm_on_start_called: [253034474,com.test.launchmode.SingleTaskActivity,handleStartActivity]
03-01 17:52:13.578 15874 15874 I launchmode_test: SingleTaskActivity#onNewIntent
03-01 17:52:13.579 15874 15874 I wm_on_resume_called: [253034474,com.test.launchmode.SingleTaskActivity,RESUME_ACTIVITY]
03-01 17:52:13.579 15874 15874 I wm_on_top_resumed_gained_called: [253034474,com.test.launchmode.SingleTaskActivity,topWhenResuming]
03-01 17:52:14.229  1483  1508 I wm_destroy_activity: [0,210771564,100,com.test.launchmode/.StandardActivity,finish-imm:idle]
03-01 17:52:14.363 15874 15874 I wm_on_stop_called: [210771564,com.test.launchmode.StandardActivity,LIFECYCLER_STOP_ACTIVITY]
03-01 17:52:14.365 15874 15874 I wm_on_destroy_called: [210771564,com.test.launchmode.StandardActivity,performDestroy] 

和Intent.FLAG_ACTIVITY_CLEAR_TOP是一样的效果。

3.2.4 启动设置了不同的taskAffinity的SingleTaskActivity

在3.2.1中,我本来以为创建SingleTaskActivity的时候,会为其创建一个新的Task,但是实际上SingleTaskActivity还是在现有的Task中启动了。跟了一下Activity启动的流程,发现,如果正在启动的Activity的taskAffinity和现存的某个Task的rootAffinity成员变量符合,那么这个Activity是有可能启动到这个Task中的,而不会去创建新的Task。

查看一下taskAffinity的定义:

 
     

渣翻:指定Activity具有“亲和性”的Task名称。与应用程序标签一起使用(为应用程序中的所有Activity提供默认的affinity),或与Activity标签一起使用(为该组件提供特定的affinity)。此属性的默认值与包名相同,表明manifest中的所有Activity通常应该被用户视为单个“应用程序”。您可以使用此属性来修改该行为:如果从用户的角度来看,Activity是另外的一个Task的一部分,则为Activity提供一个另外一个Task的affinity,或者为没有与任何Task关联的Activity使用一个空字符串。

SingleTaskActivity由于没有显式指定一个taskAffinity属性,因此用的就是默认的包名,即”com.test.launchmode“,所以就会启动到现有的Task中。

这里我们修改SingleTaskActivity的taskAffinity属性:

android:taskAffinity="com.single.task" 

以MainActivity为起点,再尝试启动SingleTaskActivity:

 #7 Task=107 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{e7a99fa u0 com.test.launchmode/.SingleTaskActivity t107} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=106 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{94a375c u0 com.test.launchmode/.MainActivity t106} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

果然设置了一个独特的taskAffinity,SingleTaskActivity就可以启动到另外一个Task中。

3.2.5 SingleTaskActivity的一个实例存在于某个后台Task中时从前台Task启动SingleTaskActivity

接3.2.4,通过SingleTaskActivity启动StandardActivity:

 #7 Task=107 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{b2c985e u0 com.test.launchmode/.StandardActivity t107} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{e7a99fa u0 com.test.launchmode/.SingleTaskActivity t107} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=106 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{94a375c u0 com.test.launchmode/.MainActivity t106} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

新的StandardActivity启动到了SingleTaskActivity所在的Task中。

然后将MainActivity所在的Task移动到前台:

 #7 Task=106 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{94a375c u0 com.test.launchmode/.MainActivity t106} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #5 Task=107 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{b2c985e u0 com.test.launchmode/.StandardActivity t107} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{e7a99fa u0 com.test.launchmode/.SingleTaskActivity t107} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

再次尝试通过MainActivity去启动SingleTaskActivity:

 #7 Task=107 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{e7a99fa u0 com.test.launchmode/.SingleTaskActivity t107} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=106 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{94a375c u0 com.test.launchmode/.MainActivity t106} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

SingleTaskActivity所在的Task#107移动到前台,SingleTaskActivity收到Activity.onNewIntent回调,并且StandardActivity被干掉:

03-01 19:10:58.807  1483  1501 I wm_task_moved: [107,1,7]
03-01 19:10:58.807  1483  1501 I wm_task_to_front: [0,107]
03-01 19:10:58.815  1483  1501 I wm_focused_root_task: [0,0,107,106,bringingFoundTaskToFront]
03-01 19:10:58.829  1483  1501 I wm_set_resumed_activity: [0,com.test.launchmode/.StandardActivity,bringingFoundTaskToFront]
03-01 19:10:58.833  1483  1501 I wm_finish_activity: [0,187471966,107,com.test.launchmode/.StandardActivity,clear-task-stack]
03-01 19:10:58.834  1483  1501 I wm_destroy_activity: [0,187471966,107,com.test.launchmode/.StandardActivity,finish-imm:finishIfPossible]
03-01 19:10:58.839  1483  1501 I wm_new_intent: [0,242915834,107,com.test.launchmode/.SingleTaskActivity,NULL,NULL,NULL,268435456]
03-01 19:10:58.855  1483  1501 I wm_pause_activity: [0,155858780,com.test.launchmode/.MainActivity,userLeaving=true,pauseBackTasks]
03-01 19:10:58.920 20840 20840 I wm_on_top_resumed_lost_called: [155858780,com.test.launchmode.MainActivity,topStateChangedWhenResumed]
03-01 19:10:58.948 20840 20840 I wm_on_destroy_called: [187471966,com.test.launchmode.StandardActivity,performDestroy]
03-01 19:10:59.080 20840 20840 I wm_on_paused_called: [155858780,com.test.launchmode.MainActivity,performPause]
03-01 19:10:59.169  1483  1501 I wm_set_resumed_activity: [0,com.test.launchmode/.SingleTaskActivity,resumeTopActivityInnerLocked]
03-01 19:10:59.177  1483  1501 I wm_add_to_stopping: [0,155858780,com.test.launchmode/.MainActivity,makeInvisible]
03-01 19:10:59.216  1483  1501 I wm_resume_activity: [0,242915834,107,com.test.launchmode/.SingleTaskActivity]
03-01 19:10:59.308 20840 20840 I wm_on_restart_called: [242915834,com.test.launchmode.SingleTaskActivity,performRestartActivity]
03-01 19:10:59.309 20840 20840 I wm_on_start_called: [242915834,com.test.launchmode.SingleTaskActivity,handleStartActivity]
03-01 19:10:59.309 20840 20840 I launchmode_test: SingleTaskActivity#onNewIntent
03-01 19:10:59.310 20840 20840 I wm_on_resume_called: [242915834,com.test.launchmode.SingleTaskActivity,RESUME_ACTIVITY]
03-01 19:10:59.310 20840 20840 I wm_on_top_resumed_gained_called: [242915834,com.test.launchmode.SingleTaskActivity,topWhenResuming]
03-01 19:11:00.645  1483  1508 I wm_stop_activity: [0,155858780,com.test.launchmode/.MainActivity]
03-01 19:11:00.789 20840 20840 I wm_on_stop_called: [155858780,com.test.launchmode.MainActivity,STOP_ACTIVITY_ITEM] 

销毁StandardActivity的逻辑和3.2.3是一样的。

4 singleInstance

4.1 singleInstance定义

 
      

1)、渣翻:

这个Activity只允许运行一个实例。这个Activity得到一个唯一的Task,只有它自己在运行;如果它再次以相同的Intent启动,那么该Task将会被移动到前台,并且它的Activity.onNewIntent()方法被调用。如果这个Activity尝试启动一个新Activity,这个新活动将在一个单独的Task中启动。

2)、google文档:

“singleInstance”

与 “singleTask” 相似,唯一不同的是系统不会将任何其他 Activity 启动到包含该实例的任务中。该 Activity 始终是其任务唯一的成员;由该 Activity 启动的任何 Activity 都会在其他的任务中打开。

4.2 singleInstance实际应用

新建一个launchMode声明为singleInstance的Activity,SingleInstanceActivity。

4.2.1 启动SingleInstanceActivity

以MainActivity为起点:

 #6 Task=94 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{a19254e u0 com.test.launchmode/.MainActivity t94} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

启动SingleInstanceActivity:

 #7 Task=95 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{3211027 u0 com.test.launchmode/.SingleInstanceActivity t95} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=94 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{a19254e u0 com.test.launchmode/.MainActivity t94} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

此时为新启动的SingleInstanceActivity创建了一个新的Task#95,并且Task#95移动到前台。

4.2.2 在非SingleInstanceActivity所在的Task尝试创建一个新的SingleInstanceActivity实例

接4.2.1,切换到MainActivity所在的Task#94:

 #7 Task=94 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{eea3b93 u0 com.test.launchmode/.MainActivity t94} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=95 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{3211027 u0 com.test.launchmode/.SingleInstanceActivity t95} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

在MainActivity界面再次尝试启动SingleInstanceActivity:

 #7 Task=95 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{3211027 u0 com.test.launchmode/.SingleInstanceActivity t95} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=94 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{eea3b93 u0 com.test.launchmode/.MainActivity t94} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

之前创建的那个SingleInstanceActivity实例所在的Task#95整个被移动到前台,并不会再创建一个新的实例。

4.2.3 在SingleInstanceActivity所在的Task尝试创建一个新的SingleInstanceActivity实例

接4.2.2,再尝试启动SingleInstanceActivity:

结果是并不会创建一个新的实例,只有SingleInstanceActivity收到Activity.onNewIntent回调:

03-01 16:34:55.132  1483  1710 I wm_new_intent: [0,52498471,95,com.test.launchmode/.SingleInstanceActivity,NULL,NULL,NULL,268435456]
03-01 16:34:55.135  1483  1710 I wm_task_moved: [95,1,7]
03-01 16:34:55.142  1483  1710 I wm_set_resumed_activity: [0,com.test.launchmode/.SingleInstanceActivity,positionChildAt]
03-01 16:34:55.195 12995 12995 I wm_on_top_resumed_lost_called: [52498471,com.test.launchmode.SingleInstanceActivity,pausing]
03-01 16:34:55.196 12995 12995 I wm_on_paused_called: [52498471,com.test.launchmode.SingleInstanceActivity,performPause]
03-01 16:34:55.196 12995 12995 I launchmode_test: SingleInstance#onNewIntent
03-01 16:34:55.196 12995 12995 I wm_on_resume_called: [52498471,com.test.launchmode.SingleInstanceActivity,LIFECYCLER_RESUME_ACTIVITY]
03-01 16:34:55.196 12995 12995 I wm_on_top_resumed_gained_called: [52498471,com.test.launchmode.SingleInstanceActivity,topWhenResuming] 

4.2.4 在SingleInstanceActivity所在的Task启动其他Activity

以SingleInstanceActivity为起点:

 #6 Task=98 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{e074c42 u0 com.test.launchmode/.SingleInstanceActivity t98} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

启动StandardActivity:

 #7 Task=99 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{47012ae u0 com.test.launchmode/.StandardActivity t99} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=98 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{e074c42 u0 com.test.launchmode/.SingleInstanceActivity t98} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

StandardActivity在一个新的Task,Task#99中被启动。

5 singleInstancePerTask

5.1 singleInstancePerTask定义

Android 12新增。

 
         

渣翻:

该Activity只能作为Task的root Activity运行,即创建该Task的第一个Activity,因此在一个Task中只能有一个该Activity的实例。与singleTask启动模式相比,如果设置了FLAG_ACTIVITY_MULTIPLE_TASK或FLAG_ACTIVITY_NEW_DOCUMENT,这个activity可以在不同的Task中多个实例中启动。

5.2 singleInstancePerTask实际应用

新建一个launchMode声明为singleInstancePerTask的Activity,SingleInstancePerTaskActivity。

5.2.1 启动SingleInstancePerTaskActivity

以MainActivity为起点,启动SingleInstancePerTaskActivity:

 #7 Task=230 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{91f591f u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=229 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{37dc04d u0 com.test.launchmodetest/.MainActivity t229} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

看到这里直接为新启动的SingleInstancePerTaskActivity创建了一个新的Task#230,而无需为其设置一个不同的taskAffinity。

5.2.2 当SingleInstancePerTaskActivity位于当前Task top时启动SingleInstancePerTaskActivity

接5.2.1,当启动了SingleInstancePerTaskActivity,且为其创建了一个Task#230后,尝试再启动SingleInstancePerTaskActivity,发现SingleInstancePerTaskActivity不会重复启动,而是现有的实例收到Activity.onNewIntent回调:

03-03 09:52:40.023  1490  1723 I wm_new_intent: [0,153049375,230,com.test.launchmodetest/.SingleInstancePerTaskActivity,NULL,NULL,NULL,268435456]
03-03 09:52:40.025  1490  1723 I wm_task_moved: [230,1,7]
03-03 09:52:40.030  1490  1723 I wm_set_resumed_activity: [0,com.test.launchmodetest/.SingleInstancePerTaskActivity,positionChildAt]
03-03 09:52:40.076 30409 30409 I wm_on_top_resumed_lost_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,pausing]
03-03 09:52:40.077 30409 30409 I wm_on_paused_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,performPause]
03-03 09:52:40.077 30409 30409 I launchmode_test: SingleInstancePerTaskActivity#onNewIntent
03-03 09:52:40.078 30409 30409 I wm_on_resume_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,LIFECYCLER_RESUME_ACTIVITY]
03-03 09:52:40.079 30409 30409 I wm_on_top_resumed_gained_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,topWhenResuming] 

5.2.3 当SingleInstancePerTaskActivity没有位于当前Task top时启动SingleInstancePerTaskActivity

接5.2.1,先通过SingleInstancePerTaskActivity创建一个StandardActivity:

 #7 Task=230 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{eea3628 u0 com.test.launchmodetest/.StandardActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{91f591f u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

然后再去启动SingleInstancePerTaskActivity:

 #7 Task=230 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{91f591f u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

结果是StandardActivity被销毁,SingleInstancePerTaskActivity现有的实例收到Activity.onNewIntent回调:

03-03 09:58:44.128  1490  3749 I wm_finish_activity: [0,250230312,230,com.test.launchmodetest/.StandardActivity,clear-task-stack]
03-03 09:58:44.133  1490  3749 I wm_pause_activity: [0,250230312,com.test.launchmodetest/.StandardActivity,userLeaving=false,finish]
03-03 09:58:44.137  1490  3749 I wm_new_intent: [0,153049375,230,com.test.launchmodetest/.SingleInstancePerTaskActivity,NULL,NULL,NULL,268435456]
03-03 09:58:44.138  1490  3749 I wm_task_moved: [230,1,7]
03-03 09:58:44.207 30409 30409 I wm_on_top_resumed_lost_called: [250230312,com.test.launchmodetest.StandardActivity,topStateChangedWhenResumed]
03-03 09:58:44.214 30409 30409 I wm_on_paused_called: [250230312,com.test.launchmodetest.StandardActivity,performPause]
03-03 09:58:44.226  1490  2226 I wm_add_to_stopping: [0,250230312,com.test.launchmodetest/.StandardActivity,completeFinishing]
03-03 09:58:44.248  1490  2226 I wm_set_resumed_activity: [0,com.test.launchmodetest/.SingleInstancePerTaskActivity,resumeTopActivityInnerLocked]
03-03 09:58:44.287  1490  2226 I wm_resume_activity: [0,153049375,230,com.test.launchmodetest/.SingleInstancePerTaskActivity]
03-03 09:58:44.369 30409 30409 I wm_on_restart_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,performRestartActivity]
03-03 09:58:44.369 30409 30409 I wm_on_start_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,handleStartActivity]
03-03 09:58:44.370 30409 30409 I launchmode_test: SingleInstancePerTaskActivity#onNewIntent
03-03 09:58:44.370 30409 30409 I wm_on_resume_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,RESUME_ACTIVITY]
03-03 09:58:44.370 30409 30409 I wm_on_top_resumed_gained_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,topWhenResuming]
03-03 09:58:44.969  1490  1515 I wm_destroy_activity: [0,250230312,230,com.test.launchmodetest/.StandardActivity,finish-imm:idle]
03-03 09:58:45.104 30409 30409 I wm_on_stop_called: [250230312,com.test.launchmodetest.StandardActivity,LIFECYCLER_STOP_ACTIVITY]
03-03 09:58:45.105 30409 30409 I wm_on_destroy_called: [250230312,com.test.launchmodetest.StandardActivity,performDestroy] 

5.2.4 当SingleInstancePerTaskActivity存在的Task没有处于前台时去启动SingleInstancePerTaskActivity

接5.2.1,先通过SingleInstancePerTaskActivity创建一个StandardActivity,然后将Task切换到Task#229:

 #7 Task=229 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{37dc04d u0 com.test.launchmodetest/.MainActivity t229} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=230 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{db261fd u0 com.test.launchmodetest/.StandardActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{91f591f u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

然后通过Task#229的MainActivity再去启动SingleInstancePerTaskActivity:

 #7 Task=230 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{91f591f u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t230} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=229 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{37dc04d u0 com.test.launchmodetest/.MainActivity t229} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

结果Task#230移动到前台,并且StandardActivity被销毁,SingleInstancePerTaskActivity现有的实例收到Activity.onNewIntent回调:

03-03 10:02:35.383  1490  8118 I wm_task_moved: [230,1,7]
03-03 10:02:35.384  1490  8118 I wm_task_to_front: [0,230]
03-03 10:02:35.402  1490  8118 I wm_focused_root_task: [0,0,230,229,bringingFoundTaskToFront]
03-03 10:02:35.427  1490  8118 I wm_set_resumed_activity: [0,com.test.launchmodetest/.StandardActivity,bringingFoundTaskToFront]
03-03 10:02:35.430  1490  8118 I wm_finish_activity: [0,229794301,230,com.test.launchmodetest/.StandardActivity,clear-task-stack]
03-03 10:02:35.431  1490  8118 I wm_destroy_activity: [0,229794301,230,com.test.launchmodetest/.StandardActivity,finish-imm:finishIfPossible]
03-03 10:02:35.434  1490  8118 I wm_new_intent: [0,153049375,230,com.test.launchmodetest/.SingleInstancePerTaskActivity,NULL,NULL,NULL,268435456]
03-03 10:02:35.447  1490  8118 I wm_pause_activity: [0,58572877,com.test.launchmodetest/.MainActivity,userLeaving=true,pauseBackTasks]
03-03 10:02:35.489 30409 30409 I wm_on_top_resumed_lost_called: [58572877,com.test.launchmodetest.MainActivity,topStateChangedWhenResumed]
03-03 10:02:35.513 30409 30409 I wm_on_destroy_called: [229794301,com.test.launchmodetest.StandardActivity,performDestroy]
03-03 10:02:35.562 30409 30409 I wm_on_paused_called: [58572877,com.test.launchmodetest.MainActivity,performPause]
03-03 10:02:35.728  1490  2524 I wm_set_resumed_activity: [0,com.test.launchmodetest/.SingleInstancePerTaskActivity,resumeTopActivityInnerLocked]
03-03 10:02:35.749  1490  2524 I wm_add_to_stopping: [0,58572877,com.test.launchmodetest/.MainActivity,makeInvisible]
03-03 10:02:35.833  1490  2524 I wm_resume_activity: [0,153049375,230,com.test.launchmodetest/.SingleInstancePerTaskActivity]
03-03 10:02:35.949 30409 30409 I wm_on_restart_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,performRestartActivity]
03-03 10:02:35.949 30409 30409 I wm_on_start_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,handleStartActivity]
03-03 10:02:35.950 30409 30409 I launchmode_test: SingleInstancePerTaskActivity#onNewIntent
03-03 10:02:35.950 30409 30409 I wm_on_resume_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,RESUME_ACTIVITY]
03-03 10:02:35.951 30409 30409 I wm_on_top_resumed_gained_called: [153049375,com.test.launchmodetest.SingleInstancePerTaskActivity,topWhenResuming]
03-03 10:02:37.430  1490  1515 I wm_stop_activity: [0,58572877,com.test.launchmodetest/.MainActivity]
03-03 10:02:37.829 30409 30409 I wm_on_stop_called: [58572877,com.test.launchmodetest.MainActivity,STOP_ACTIVITY_ITEM] 

5.2.5 结合Intent.FLAG_ACTIVITY_MULTIPLE_TASK和Intent.FLAG_ACTIVITY_NEW_DOCUMENT

分析了上面四种情况,发现singleInstancePerTask的作用和singleTask几乎一样,不过singleInstancePerTask不需要为启动的Activity设置一个特殊的taskAffinity才能创建一个新的Task。

根据singleInstancePerTask的定义,该launchMode和Intent.FLAG_ACTIVITY_MULTIPLE_TASK或Intent.FLAG_ACTIVITY_NEW_DOCUMENT结合使用可以将启动的Activity在多个Task中多次实例化,那么来看具体是怎么样的。这里每次启动SingleInstancePerTaskActivity时,都为启动Intent添加这两个flag:

intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); 

还是以MainActivity为起点,然后启动singleInstancePerTask,根据5.2.1,知道此时会为新启动的singleInstancePerTask创建一个Task:

 #7 Task=236 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{3a0de63 u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t236} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=235 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{766c588 u0 com.test.launchmodetest/.MainActivity t235} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

接着通过singleInstancePerTask再去启动singleInstancePerTask:

 #8 Task=237 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{518568f u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t237} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #7 Task=236 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{3a0de63 u0 com.test.launchmodetest/.SingleInstancePerTaskActivity t236} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=235 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{766c588 u0 com.test.launchmodetest/.MainActivity t235} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

果然不同于5.2.2,这里又创建了一个singleInstancePerTask的新实例,且创建了一个新的Task#237。

三、使用 Intent 标记

启动 Activity 时,通过在startActivity()的 intent 中添加相应的flag来修改 Activity 与其Task的默认关联。

1 FLAG_ACTIVITY_NEW_TASK

1.1 FLAG_ACTIVITY_NEW_TASK定义

 /**
     * If set, this activity will become the start of a new task on this
     * history stack.  A task (from the activity that started it to the
     * next task activity) defines an atomic group of activities that the
     * user can move to.  Tasks can be moved to the foreground and background;
     * all of the activities inside of a particular task always remain in
     * the same order.  See
     * Tasks and Back
     * Stack for more information about tasks.
     *
     * 

This flag is generally used by activities that want * to present a "launcher" style behavior: they give the user a list of * separate things that can be done, which otherwise run completely * independently of the activity launching them. * *

When using this flag, if a task is already running for the activity * you are now starting, then a new activity will not be started; instead, * the current task will simply be brought to the front of the screen with * the state it was last in. See {@link #FLAG_ACTIVITY_MULTIPLE_TASK} for a flag * to disable this behavior. * *

This flag can not be used when the caller is requesting a result from * the activity being launched. */ public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;

1)、渣翻: 如果设置,这个Activity将成为一个新Task的堆栈中起始Activity。一个Task(从启动它的Activity到下一个Task Activity)定义了一个用户可以移动到的原子Activity组。Task可以移动到前台和后台;特定Task中的所有Activity始终保持相同的顺序。

这个flag通常被想要呈现一个”Launcher”风格行为的Activity使用:它们给用户一个可以做的单独事情的列表,否则这些事情完全独立于启动它们的Activity运行。 当使用这个flag时,如果一个task已经正在运行你启动的activity,那么一个新的activity将不会被启动;相反,当前Task将简单地伴随着它最后一次进入的状态被带到屏幕前面。参见FLAG_ACTIVITY_MULTIPLE_TASK来禁用此行为。

当调用者从启动的Activity请求一个结果时,不能使用此flag。

2)、google文档:

FLAG_ACTIVITY_NEW_TASK

在新Task中启动 Activity。如果您现在启动的 Activity 已经有Task在运行,则系统会将该Task转到前台并恢复其最后的状态,而 Activity 将在onNewIntent()中收到新的 intent。

这与 “singleTask” launchMode值产生的行为相同。

1.2 FLAG_ACTIVITY_NEW_TASK实际应用

1.2.1 以FLAG_ACTIVITY_NEW_TASK的方式启动Activity

这里我直接用MainActivty启动StandardActivity,启动Intent中加入FLAG_ACTIVITY_NEW_TASK:

 #6 Task=134 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{bf67e76 u0 com.test.launchmode/.StandardActivity t134} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{887cfac u0 com.test.launchmode/.MainActivity t134} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

新启动的StandardActivity并没有像预料那样以一个新Task的方式启动,而是仍然创建在了当前Task#134中。

1.2.2 在要启动的Activity已经位于Task的top的情况下以FLAG_ACTIVITY_NEW_TASK的方式启动Activity

接1.2.1,当已经有一个StandardActivity位于当前Task的top时,再去以FLAG_ACTIVITY_NEW_TASK的方式启动StandardActivity:

 #6 Task=134 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #2 ActivityRecord{4ced944 u0 com.test.launchmode/.StandardActivity t193} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #1 ActivityRecord{bf67e76 u0 com.test.launchmode/.StandardActivity t134} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{887cfac u0 com.test.launchmode/.MainActivity t134} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAfHO36n-1652865254905)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8496833b66024523a9820373516401c8~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

和launchMode为“singleTask”的情况也不一样,直接创建了一个新实例,singleTask则是复用了旧实例。

1.2.3 以FLAG_ACTIVITY_NEW_TASK的方式启动一个taskAffinity与App包名不同的Activity

根据google文档的描述,FLAG_ACTIVITY_NEW_TASK产生的行为与launchMode中的singleTask相同,那么没有创建新的Task的原因应该也是一样的,因此我这里新建了一个DifferentAffinityActivity,给它设置一个不同于App包名的taskAffinity,然后通过MainActivity以FLAG_ACTIVITY_NEW_TASK的方式去启动DifferentAffinityActivity:

 #7 Task=2 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{dc31b80 u0 com.test.launchmodetest/.DifferentAffinityActivity t210} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=1 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{ecdd154 u0 com.test.launchmodetest/.MainActivity t209} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200] 

成功,系统为StandardActivity创建了一个Task#2。

另外试验,如果只是为DifferentAffinityActivity设置一个特殊的taskAffinity,但是启动它的时候不设置FLAG_ACTIVITY_NEW_TASK,是不会创建新Task的。

1.2.4 在taskAffinity不同的Task中以FLAG_ACTIVITY_NEW_TASK启动Activity(1)

先启动MainActivity,然后再通过MainActivity以FLAG_ACTIVITY_NEW_TASK的方式启动一个StandardActivity,根据1.2.1可知,这两个Activity会在同一个Task中。

接着通过StandardActivity以FLAG_ACTIVITY_NEW_TASK的方式启动一个不同taskAffinity的DifferentAffinityActivity,根据1.2.3可知,系统会为DifferentAffinityActivity创建一个新的Task:

 #7 Task=208 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
         #0 ActivityRecord{82c008a u0 com.test.launchmodetest/.DifferentAffinityActivity t208} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1920,1200]
        #6 Task=207 type=standard mode=fullscreen overrid

相关文章