关于Android的Intent.FLAG_ACTIVITY_CLEAR_TOP
今天写代码遇到了一个问题:有如下几个Activity

A - B - C

当 B - A - B 跳转的时候,使用Intent的FLAG_ACTIVITY_CLEAR_TOP会让第一个B和第二个A,destory掉

但是当B - A - C跳转的时候不会调用B和A的destory

其实这个问题以前遇到过,今天遇到的时候又忘记了。查看API文档才发现原因,所以这里记录一下避免下次又忘记了:


public static final int FLAG_ACTIVITY_CLEAR_TOP
Added in API level 1

If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.


文档上说,如果设置这个属性,是当要启动的Activity已经存在当前Task中,才会在启动的时候销毁其他的Activity。

所以上面当A跳C的时候不满足此条件。


当然如果你想实现这个效果可以使用:

it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);


不过不幸的是,此方法要求最低API为11



FLAG_ACTIVITY_CLEAR_TASK :如果在调用Context.startActivity时传递这个标记,将会导致任何用来放置该activity的已经存在的task里面的已经存在的activity先清空,然后该activity再在该task中启动,也就是说,这个新启动的activity变为了这个空tas的根activity.所有老的activity都结束掉。该标志必须和FLAG_ACTIVITY_NEW_TASK一起使用。

示例:

我们有三个activity:MainActivity、ActivityA、ActivityB. 依次从MainActivity中启动ActivityA,从ActivityA中启动ActivityB.

首先我们所有的都使用缺省的,也即没有设置taskAffinity、launchMode,启动activity时Intent也不带标记,我们看一下启动B之后的堆栈:


  1. ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)    

  2.  Main stack:    

  3.    TaskRecord{4199dd68 #56 A com.leaves.ipanel U 0}    

  4.    Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.leaves.ipanel/.MainActivity }    

  5.      Hist #3: ActivityRecord{4140fdf8 u0 com.leaves.ipanel/.ActivityB}    

  6.        Intent { act=com.leaves.ipanel.ActivityB cmp=com.leaves.ipanel/.ActivityB }    

  7.        Proce***ecord{41517e80 13350:com.leaves.ipanel/u0a10061}    

  8.      Hist #2: ActivityRecord{413ff7e8 u0 com.leaves.ipanel/.ActivityA}    

  9.        Intent { act=com.leaves.ipanel.ActivityA cmp=com.leaves.ipanel/.ActivityA }    

  10.        Proce***ecord{41517e80 13350:com.leaves.ipanel/u0a10061}    

  11.      Hist #1: ActivityRecord{413f8b28 u0 com.leaves.ipanel/.MainActivity}    

  12.        Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.leaves.ipanel/.MainActivity }    

  13.        Proce***ecord{41517e80 13350:com.leaves.ipanel/u0a10061}    

  14.    TaskRecord{41350f60 #2 A com.android.launcher U 0}    

  15.    Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10600000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  16.      Hist #0: ActivityRecord{41616790 u0 com.android.launcher/com.android.launcher2.Launcher}    

  17.        Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  18.        Proce***ecord{41615818 628:com.android.launcher/1000}    

可以看到三者在同一个task中,且都存在。



接下来我们在启动ActivityB时添加FLAG_ACTIVITY_CLEAR_TASK和FLAG_ACTIVITY_NEW_TASK

  1. publicvoid onClick(View v) {    

  2. // TODO Auto-generated method stub  

  3.    Log.i(TAG, "--onClick--task id = " + getCurrentTaskId());      

  4.    Intent intent = new Intent("com.leaves.ipanel.ActivityB");      

  5.    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);    

  6.    startActivity(intent);    

  7. }    

再看下启动ActivityB之后的堆栈:


  1. ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)    

  2.  Main stack:    

  3.    TaskRecord{4245bd10 #57 A com.leaves.ipanel U 0}    

  4.    Intent { act=com.leaves.ipanel.ActivityB flg=0x10008000 cmp=com.leaves.ipanel/.ActivityB }    

  5.      Hist #1: ActivityRecord{413f8b28 u0 com.leaves.ipanel/.ActivityB}    

  6.        Intent { act=com.leaves.ipanel.ActivityB flg=0x10008000 cmp=com.leaves.ipanel/.ActivityB }    

  7.        Proce***ecord{41413010 13441:com.leaves.ipanel/u0a10061}    

  8.    TaskRecord{41350f60 #2 A com.android.launcher U 0}    

  9.    Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10600000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  10.      Hist #0: ActivityRecord{41616790 u0 com.android.launcher/com.android.launcher2.Launcher}    

  11.        Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  12.        Proce***ecord{41615818 628:com.android.launcher/1000}    

可以看到,MainActivity和ActivityA都被结束掉了,原因就是因为该task用来装载ActivityB,而启动时又设置了FLAG_ACTIVITY_CLEAR_TASK和FLAG_ACTIVITY_NEW_TASK