singleInstancePerTask介绍

singleInstancePerTask为android12新增的在standard、singleTop、singleTask、singleInstance之后的第五种启动模式。
Android12的对于singleInstancePerTask描述如下:

           <!-- The activity can only be running as the root activity of the task, the first activity
            that created the task, and therefore there will only be one instance of this activity
            in a task. In constrast to the {@code singleTask} launch mode, this activity can be
            started in multiple instances in different tasks if the
            {@code FLAG_ACTIVITY_MULTIPLE_TASK } or {@code FLAG_ACTIVITY_NEW_DOCUMENT} is set.-->`
            <enum name="singleInstancePerTask" value="4" />

翻译为:
Activity只能作为任务栈的根Activity(第一个Activity)运行创建了任务栈,因此此Activity将只有一个实例在任务栈中。在 {@code singleTask} 启动模式的约束下,此活动可以在不同任务栈的多个实例中启动,如果{@code FLAG_ACTIVITY_MULTIPLE_TASK } 或 {@code FLAG_ACTIVITY_NEW_DOCUMENT} 已设置。

从中描述可以了解singleInstancePerTask的作用和singleTask几乎一样,不过singleInstancePerTask不需要为启动的Activity设置一个特殊的taskAffinity才能创建一个新的Task。
下面做一个测验查看启动activity时任务栈的情况:
使用adb shell dumpsys activity activities | grep com.example.systemapp查看进程的activity任务栈状态。以默认standard启动模式的MainActivity来启动声明singleInstancePerTask启动模式的SingleInstancePerTaskActivity,接着再启动声明standard启动模式StandardActivity。
在MainActivity启动SingleInstancePerTaskActivity的任务栈情况如下:

  • Task{81c692c #19 type=standard A=10147:com.example.systemapp U=0 visible=true mode=fullscreen translucent=false sz=1}
    * ActivityRecord{d0488df u0 com.example.systemapp/.SingleInstancePerTaskActivity t19}
    * Task{e1d436a #18 type=standard A=10147:com.example.systemapp U=0 visible=false mode=fullscreen translucent=true sz=1}
    * ActivityRecord{35a6661 u0 com.example.systemapp/.MainActivity t18}

其中由于SingleInstancePerTaskActivity为singleInstancePerTask的启动模式,会新建一条新的任务栈,可以看到有两条任务栈。
接下来在MainActivity启动SingleInstancePerTaskActivity后再从SingleInstancePerTaskActivity启动StandardActivity的任务栈情况如下:

  • Task{81c692c #19 type=standard A=10147:com.example.systemapp U=0 visible=true mode=fullscreen translucent=false sz=2}
    * ActivityRecord{455ff31 u0 com.example.systemapp/.StandardActivity t19}
    * ActivityRecord{d0488df u0 com.example.systemapp/.SingleInstancePerTaskActivity t19}
    * Task{e1d436a #18 type=standard A=10147:com.example.systemapp U=0 visible=false mode=fullscreen translucent=true sz=1}
    * ActivityRecord{35a6661 u0 com.example.systemapp/.MainActivity t18}

可以看到还是只有两条任务栈,StandardActivity存在于SingleInstancePerTaskActivity的任务栈中。
接着再从StandardActivity再去启动SingleInstancePerTaskActivity。

  • Task{81c692c #19 type=standard A=10147:com.example.systemapp U=0 visible=true mode=fullscreen translucent=false sz=1}
    * ActivityRecord{d0488df u0 com.example.systemapp/.SingleInstancePerTaskActivity t19}
    * Task{e1d436a #18 type=standard A=10147:com.example.systemapp U=0 visible=false mode=fullscreen translucent=true sz=1}
    * ActivityRecord{35a6661 u0 com.example.systemapp/.MainActivity t18}

可以看到任务栈还是两条,只不过SingleInstancePerTaskActivity并不会重新创建而是走了onNewIntent,而StandardActivity和SingleInstancePerTaskActivity同为一个任务栈,因此被销毁,这点类似singleTask的作用。

注意需要在Android12的真机或者模拟器上使用此模式,否则默认为standard模式

和Intent.FLAG_ACTIVITY_MULTIPLE_TASK或Intent.FLAG_ACTIVITY_NEW_DOCUMENT搭配使用

和Intent.FLAG_ACTIVITY_MULTIPLE_TASK或Intent.FLAG_ACTIVITY_NEW_DOCUMENT结合使用。SingleInstancePerTaskActivity再启动SingleInstancePerTaskActivity,则会新启动SingleInstancePerTaskActivity并创建一个新任务栈。如果不设置则只走onNewIntent的回调并不会重新onCreate。

     Intent intent = new Intent(SingleInstancePerTaskActivity.this, SingleInstancePerTaskActivity.class);
     intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
     //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
     startActivity(intent);

任务栈情况如下:

  • Task{bf82c4b #29 type=standard A=10147:com.example.systemapp U=0 visible=true mode=fullscreen translucent=false sz=1}
    * ActivityRecord{ea24a0e u0 com.example.systemapp/.SingleInstancePerTaskActivity t29}
    * Task{68f9c5f #28 type=standard A=10147:com.example.systemapp U=0 visible=false mode=fullscreen translucent=true sz=1}
    * ActivityRecord{a528cfe u0 com.example.systemapp/.SingleInstancePerTaskActivity t28}
    * Task{ad4567a #27 type=standard A=10147:com.example.systemapp U=0 visible=false mode=fullscreen translucent=true sz=1}
    * ActivityRecord{86222ed u0 com.example.systemapp/.MainActivity t27}

taskAffinity介绍

taskAffinity是指Activity的任务栈亲和度,即任务归属,代表该Activity属于哪个任务栈。
使用场景:
1.一般根据taskAffinity重新为Activity选择宿主任务栈(与allowTaskReparenting属性配合使用)
2.启动一个Activity过程中Intent使用了FLAG_ACTIVITY_NEW_TASK标记,根据taskAffinity查找或创建一个新的具有对应taskAffinity的任务栈。

注意点:taskAffinity一般singleTask搭配使用,当启动的Activity使用standard、singleTop属性时,如果只设置一个特殊的taskAffinity,但是启动它的时候不设置FLAG_ACTIVITY_NEW_TASK,是不会创建新任务栈。指定singleInstance模式和singleInstancePerTask加上taskAffinity则为新的任务栈命名。

singleInstance和singleInstancePerTask区别

singleInstance表示全局只有一个activity实例。这个Activity得到一个唯一的Task,只有它自己在运行;如果它再次以相同的Intent启动,那么该Task将会被移动到前台,并且它的Activity.onNewIntent()方法被调用。如果这个Activity尝试启动一个新Activity,这个新活动将在一个单独的任务栈中启动。而singleInstancePerTask作用和singleTask相当,只不过会为启动的Activity新建任务栈,同时配合Intent.FLAG_ACTIVITY_MULTIPLE_TASK或Intent.FLAG_ACTIVITY_NEW_DOCUMENT,singleInstancePerTask可以同时存在Activity在不同任务栈中。

更多启动模式介绍可参考此链接:【Android 12】Activity启动模式

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐