我们知道,Android为Activity的启动设定了四种启动模式,分别为:
Stardand,SingleTop,SingleInstance和SingleTask.下面我们分别进行分析
1.Stardand ::
每次创建一个新的Activity实例
通过如下命令获取stack的状态:
adb shell dumpsys activity activities
会打印出很多信息,我们只关注如下信息即可(adb shell dumpsys activity activities |grep “Run” ):
Running activities (most recent first):
TaskRecord{daa78d9 #39 A=com.main.activity U=0 StackId=1 sz=5}
Run #4: ActivityRecord{82fdf08 u0 com.example.manjc.managerbuttons/.MainActivity t39}
Run #3: ActivityRecord{4387a33 u0 com.example.manjc.managerbuttons/.MainActivity t39}
Run #2: ActivityRecord{6167f4a u0 com.example.manjc.managerbuttons/.MainActivity t39}
Run #1: ActivityRecord{7cfe642 u0 com.example.manjc.managerbuttons/.MainActivity t39}
Run #0: ActivityRecord{81f3365 u0 com.example.manjc.managerbuttons/.MainActivity t39}
可以看出当前的taskID为39,存在同一个activity的五个实例.当按下back键时候,依次退出.
2.SingleTop ::
定义三个Activity,MainActivity,SecondActivity和ThirdActivity,其中MainActivity的启动模式为SingleTop
我们依次启动三个Activity,目前的task状态如下:
Running activities (most recent first):
Run #2: ActivityRecord{9fd4813 u0 com.example.manjc.managerbuttons/.ThirdActivity t46}
Run #1: ActivityRecord{f931d9a u0 com.example.manjc.managerbuttons/.SecondActivity t46}
Run #0: ActivityRecord{277316c u0 com.example.manjc.managerbuttons/.MainActivity t46}
当我们通过ThirdActivity去启动MainActivity时候,再去查看task,得到如下状态:
Running activities (most recent first):
Run #3: ActivityRecord{74d5265 u0 com.example.manjc.managerbuttons/.MainActivity t47}
Run #2: ActivityRecord{a497da u0 com.example.manjc.managerbuttons/.ThirdActivity t47}
Run #1: ActivityRecord{c8e3a82 u0 com.example.manjc.managerbuttons/.SecondActivity t47}
Run #0: ActivityRecord{6151226 u0 com.example.manjc.managerbuttons/.MainActivity t47}
在MainActivity中,我们再启动MainActivity,以及多次启动MainActivity,均是如上的结果
我们可以看到,目前MainActivity处于栈顶,当返回时,依次退出(虽然当前task中已经存在MainActivity的实例,但是不是存在栈顶的位置,那么就会创建一个新的实例压进堆栈)
3.SingleInstance ::
定义三个Activity,MainActivity,SecondActivity和ThirdActivity,其中MainActivity的启动模式为SingleInstance
我们依次启动三个Activity,目前的task状态如下:
Running activities (most recent first):
Run #2: ActivityRecord{9fd4813 u0 com.example.manjc.managerbuttons/.ThirdActivity t46}
Run #1: ActivityRecord{f931d9a u0 com.example.manjc.managerbuttons/.SecondActivity t46}
Run #0: ActivityRecord{277316c u0 com.example.manjc.managerbuttons/.MainActivity t45}
当我们通过ThirdActivity去启动MainActivity时候,再去查看task,得到如下状态:
Running activities (most recent first):
Run #2: ActivityRecord{277316c u0 com.example.manjc.managerbuttons/.MainActivity t45}
Run #1: ActivityRecord{9fd4813 u0 com.example.manjc.managerbuttons/.ThirdActivity t46}
Run #0: ActivityRecord{f931d9a u0 com.example.manjc.managerbuttons/.SecondActivity t46}
我们可以看到,目前MainActivity处于栈顶并且在一个单独的task中,当返回时,依次退出(当退到SecondActivity时,再按依次back应用程序就退出了,不会再有MainActivity,从task中也能够看出)
4.SingleTask ::
这个启动模式是这四中启动模式最复杂的,我们还是上面的那个例子,此时我们设置SecondActivity的启动模式为SingleTask
我们依次启动三个Activity,目前的task状态如下:
Run #2: ActivityRecord{4bc308 u0 com.example.manjc.managerbuttons/.ThirdActivity t48}
Run #1: ActivityRecord{2aee33 u0 com.example.manjc.managerbuttons/.SecondActivity t48}
Run #0: ActivityRecord{4626cc2 u0 com.example.manjc.managerbuttons/.MainActivity t48}
咦,很奇怪啊,就是正常的启动三个Activity,没有什么特别的啊,task的ID也是一样的啊,怎么回事啊???
经过调查,发现跟android:taskAffinity这个属性有关系..
原来我们没有配置这三个Activity的android:taskAffinity属性,就默认为父标签application的taskAffinity属性值,我的application也没配置的话,就是默认的包名了.
那么我们对Acitivty进行配置taskAffinity属性:
MainActivity: android:taskAffinity="com.main.activity
SecondActivity: android:taskAffinity="com.second.activity
ThirdActivity: android:taskAffinity="com.main.activity
再次启动程序并依次启动Activity:
Running activities (most recent first):
Run #2: ActivityRecord{8199251 u0 com.example.manjc.managerbuttons/.ThirdActivity t65}
Run #1: ActivityRecord{4f73083 u0 com.example.manjc.managerbuttons/.SecondActivity t65}
Run #0: ActivityRecord{6989d0f u0 com.example.manjc.managerbuttons/.MainActivity t64}
从以上结果我们能够看出,在启动SecondActivity时候,因为它定义了启动模式为SingleTask并且它的taskAffinity与其他Activity的不同,那么系统将为它新建立一个task,而且我们可以看到如果后面经过它启动的Activity没有特殊说明(指定启动模式为SingleTask),那么新启动的Activity都会放进新建立的task并处于前台活动,之前的task转移到后台.
如果我们将MainActivity的启动模式也设定为SingleTask,通过ThirdActivity启动MainActivity,得到如下task信息:
Running activities (most recent first):
Run #2: ActivityRecord{6989d0f u0 com.example.manjc.managerbuttons/.MainActivity t64}
Run #1: ActivityRecord{8199251 u0 com.example.manjc.managerbuttons/.ThirdActivity t65}
Run #0: ActivityRecord{4f73083 u0 com.example.manjc.managerbuttons/.SecondActivity t65}
可以看到,当前的focus task 为t64,只含有一个Activity实例MainActivity.当按back返回时,依次退出.
下面再实验一个稍微复杂的一种情况:
定义三个Activity,MainActivity,SecondActivity,ThirdActivity和FourthActivity,其中所有的Activity的启动模式均为SingleTop,
但是MainActivity和ThirdActivity的taskAffinity相同,SecondActivity和FourthActivity的taskAffinity相同
我们依次启动,得到如下task信息:
Running activities (most recent first):
Run #3: ActivityRecord{2fe2786 u0 com.example.manjc.managerbuttons/.FourthActivity t73}
Run #2: ActivityRecord{51c6b76 u0 com.example.manjc.managerbuttons/.ThirdActivity t72}
Run #1: ActivityRecord{c4ad1a2 u0 com.example.manjc.managerbuttons/.SecondActivity t73}
Run #0: ActivityRecord{a1a106e u0 com.example.manjc.managerbuttons/.MainActivity t72}
我们退出时,这个时候需要注意!当前的focus task为t73,栈顶的Activity为FourthActivity,我们按下back键后会是什么样子的呢,我们得到如下task信息:
Running activities (most recent first):
Run #2: ActivityRecord{c4ad1a2 u0 com.example.manjc.managerbuttons/.SecondActivity t73}
Run #1: ActivityRecord{51c6b76 u0 com.example.manjc.managerbuttons/.ThirdActivity t72}
Run #0: ActivityRecord{a1a106e u0 com.example.manjc.managerbuttons/.MainActivity t72}
没错,此时SecondActivity处于栈顶,原因就是此时的focus task为t73,FourthActivity出栈以后SecondActivity就处于栈顶了呢.对,就是这样.只有当前focus的task内容为空时,后台的task才能转移到前台!
后期把对应的图补上,更直观一些!!
关于SingleTask的更详细介绍可以参考老罗的文章:
http://blog.csdn.net/luoshengyang/article/details/6714543