【基础】任务栈与启动模式

对于Android的启动模式,似乎是最简单的入门知识了,StandardSingleTopSingleTaskSingleInstance
本文重点对singleTask进行加深理解。

入门及使用

任务栈(Task)

要了解启动模式的具体表现流程,首先要了解任务栈。官网介绍说任务与回退栈,这里直接成为任务栈。

一个Application一般是由多个Activity构成,而多个Activity的管理,Android已经帮我们管理好了,使用栈方式管理,也就是先进后出,启动模式可以理解为四种不同的进栈出栈方式。而这个管理activity的栈成为任务栈。

  1. 一个app默认只有一个任务栈,由系统指定。
  2. 一个app可以存在多个任务栈,需要自己手动设置。多个任务栈时,当前activity所在栈处于前台,其余栈处于后台。

启动模式

1. standard


    
        

        
    


standard是android中默认的启动模式,如果你新建一个应用,不进行任何修改,那么MainActivity的启动模式就是standard

standard会进行重复创建实例,比如应用中有Main和A两个activity,那么Main -> A -> A -> Main这样的启动顺序,就会如下图所示:

standard重复创建实例

点击back返回,则会正常出栈,直到最后一个出栈,app关闭回到桌面。

按back键返回示意图

这种模式一般不推荐使用,会占用过多内存,页面重复。

2. singleTop 栈顶复用


只有这个activity处于栈顶位置时,不会重新创建实例,而是会使用已经创建好的实例。并且会调用onNewIntent方法,可以根据此方法获取intent实例。

singleTop示意图

应用情景:
点击通知跳转到文章详情页,如果当前用户正在文章详情页查看时进行点击,那么可以使用singleTop来确保不会重复创建实例,避免用户点击回退键时还是文章详情页。

3. singleTask 栈内只有一个实例


singleTask模式是栈内只允许存在一个实例,当这个实例已经创建,会直接使用这个实例,而不会重新创建,在这个实例上方的其他activity也将全部出栈销毁。重用实例会调用onNewIntent

比如设置MainsingleTask,打开Main后,再打开A,B,C三个默认standard的Activity,由C打开Main,则栈中只剩下Main

singleTask
注意1:singleTask 和 taskAffinity

每个activity都有taskAffinity属性,如果没有显式的指明taskAffinity,那么就等于Application指明的taskAffinity,而如果Application也没有指明,那么该taskAffinity的值就等于应用的包名。

默认情况下singleTask所在的任务栈就是app启动的默认栈,而当设置了taskAffinity后,那么启动设置singleTask的activity,那么就会新创建一个栈来存放activity。


这样一个app就存在两个任务栈。

启动流程是这样的:
a)判断当前任务栈taskAffinity是否为.myNewTask,如果是的话,直接将该activity置于当前任务栈栈顶
b)如果当前任务栈taskAffinity不为.myNewTask,则检查是否存在一个任务栈taskAffinity值为.myNewTask,如存在,则将该任务栈移到前台,并将该activity置于栈顶
c)如果并不存在一个任务栈taskAffinity值为.myNewTask,那么将会为该activity创建一个新的任务栈,该任务栈显示在前台

注意2:SingleTask && MAIN启动

每个app都会存在一个启动的activity,即点击图标进入的第一个activity


    
        
        
    

当此时的MainActivity设置android:launchMode="singleTask"时,会产生这样一个现象:回退Home后重新打开app,总是会重新打开,而不记录最后打开的页面。

这个其实就是由于栈内存在一个实例导致,因为之前已经启动过app,也就是后台存在这个app的任务栈,那么回退到Home再重新打开,首先会找到这个App对应的任务栈,而后由于启动的MainActvitySingleTask,在任务栈中已经存在,那么会直接使用这个存在的实例,又因为MainActivity处于栈底,那么启动这个已经存在的实例会将上方所有的activity都清除出栈

注意3:allowTaskReparenting && taskAffinity

activitytaskAffinity,默认指向applicationtaskAffinity,默认是mainfestpackage值,也就是常说的包名。

allowTaskReparenting这个属性很有意思,可以将activity由一个task迁移到另一个task,而将activity迁移到另一个task是又条件的:

  1. 首先指定android:allowTaskReparenting="true"
  2. 指定android:taskAffinity=".xx"这个.xx并不是你应用本身的taskAffinity,或者不同应用默认taskAffinity本身就不同,可以不指定taskAffinity
  3. 发生Task Reset,点击Home再启动APP可发生Task Reset


    
        
        
            
                

                
            
        
    


taskAffinity属性是迁移后的所指栈。

根据上述Mainfest配置,执行流程:

  1. 首先点击APP图标启动MainActivity,创建一个taskAffinitycom.example.taskb的任务栈,MainActivity入栈。
    启动APP后栈状态
  2. MainActivity启动OtherTaskActivity,那么他还是会在应用的栈中入栈。
    启动OtherTaskActivity
  3. 点击Home,发生Task Reset,应用com.example.taskb任务栈处于后台,由于OtherTaskActivity属性allowTaskReparenting="true" && taskAffinity=".othertask",所以此时这个应用后台将存在两个任务栈。
    两个任务栈
  4. 点击APP图标重新启动应用,com.example.taskb任务栈处于前台,显示MainActivitycom.example.taskb.othertask任务栈处于后台,不显示。当按回退键时,com.example.taskb任务栈清除,com.example.taskb.othertask任务栈回到前台,显示OtherTaskActivity
注意4: taskAffinity起作用只有两种情况
  1. 设置launchMode="singleTask"或者intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  2. 设置allowTaskReparenting=true并满足前面所说的情况。

应用场景:
activity设置SingleTask,退出应用清除栈。适合闪屏页+主页模式,闪屏页为MAIN入口,跳转到主页前finish闪屏页,主页启动模式为SingleTask,可以实现保存应用状态。

4. singleInstance 栈内有且只有一个实例,并可复用

任务栈中只有一个activity,如果存在,那么直接使用实例,调用onNewIntent方法。

你可能感兴趣的:(【基础】任务栈与启动模式)