对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践

对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践

前言

昨天编写了一篇博文: Activity启动模式与栈的使用小结,里面参考了下面这篇文章:

Android面试官装逼失败之:Activity的启动模式

对里面关于 FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK | singleTop 的描述有点困惑,而且昨天文章也没讲到 FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK 的情形,所以思来想去,还是写个DOMO来试试!

下面是该篇文章中的叙述:

如果同时使用了FLAG_ACTIVITY_NEW_TASK ,这个时候,目标是Activity自己所属的Task栈,如果在自己的Task中能找到一个Activity实例,则将其上面的及自身清理掉,之后重建。
对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践_第1张图片
FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK

如果同时在加上FLAG_ACTIVITY_SINGLE_TOP,会更特殊一些,如果topActivity不是目标Activity,就会去目标Task中去找,并唤起:
对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践_第2张图片
FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK| singleTop

如果topActivity是目标Activity,就直接回调topActivity的onNewIntent,无论topActivity是不是在目标Task中
对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践_第3张图片
FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK| singleTop

纸上得来终觉浅,绝知此事要躬行,下面我们就来试试,是不是和这篇文章说的一样。

准备工作

这里需要准备一些东西:代码、测试手机、adb命令。

代码其实很简单,只要创建A、B、C、D、E五个Activity,对它们设置不同的taskAffinity(这里taskAffinity居然还有格式要求),然后启动他们,如果要新开栈,需要配合FLAG_ACTIVITY_NEW_TASK跳转。






测试手机我这用的荣耀10,鸿蒙2.0.0,安卓10,代码的compileSdkVersion=31,targetSdkVersion=30。

adb命令在网上找了很久,都没找到只显示堆栈的命令,下面第一种简洁但是堆栈信息不全,第二种是全了,但是要在一堆字符里面找,不过也不麻烦,下面用的第二种。

adb shell
// 第一种
dumpsys activity top | grep ACTIVITY
// 第二种
dumpsys activity activities

测试开始

测试FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP

Activity打开方式:

M(new task) -> A -> B -> C(new task) -> D -> F

堆栈信息:

Running activities (most recent first):
      TaskRecord{747baed #160 A=10913:com.test.TestB U=0 StackId=160 sz=2}
        Run #1: ActivityRecord{6f2f783 u0 com.silencefly96.fundark/.TestActivityF t160}
        Run #0: ActivityRecord{6f0a248 u0 com.silencefly96.fundark/.TestActivityD t160}

Running activities (most recent first):
      TaskRecord{747bac7 #159 A=10913:com.test.TestA U=0 StackId=159 sz=3}
        Run #2: ActivityRecord{6f0a3c2 u0 com.silencefly96.fundark/.TestActivityC t159}
        Run #1: ActivityRecord{72c5583 u0 com.silencefly96.fundark/.TestActivityB t159}
        Run #0: ActivityRecord{72c5544 u0 com.silencefly96.fundark/.TestActivityA t159}

Running activities (most recent first):
      TaskRecord{747bbab #158 A=10913:com.silencefly96.fundark U=0 StackId=158 sz=1}
        Run #0: ActivityRecord{7256f44 u0 com.silencefly96.fundark/.MainActivity t158}

接下来:

F(new task | clear top) -> B

堆栈信息:

Running activities (most recent first):
      TaskRecord{747bac7 #159 A=10913:com.test.TestA U=0 StackId=159 sz=2}
        Run #1: ActivityRecord{72733c2 u0 com.silencefly96.fundark/.TestActivityB t159}
        Run #0: ActivityRecord{72c5544 u0 com.silencefly96.fundark/.TestActivityA t159}

Running activities (most recent first):
      TaskRecord{747baed #160 A=10913:com.test.TestB U=0 StackId=160 sz=2}
        Run #1: ActivityRecord{6f2f783 u0 com.silencefly96.fundark/.TestActivityF t160}
        Run #0: ActivityRecord{6f0a248 u0 com.silencefly96.fundark/.TestActivityD t160}

Running activities (most recent first):
      TaskRecord{747bbab #158 A=10913:com.silencefly96.fundark U=0 StackId=158 sz=1}
        Run #0: ActivityRecord{7256f44 u0 com.silencefly96.fundark/.MainActivity t158}

果然,这里任务栈TestA代替TestB到了顶层,而TestActivityB的对象从72c5583变为了72733c2,上面的TestActivityC被清除了,还算符合我们的理解。

测试 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP

接下来在上面的情况下,再加上FLAG_ACTIVITY_SINGLE_TOP,再试下复用情况:

M(new task) -> A -> B -> C(new task) -> D -> F

堆栈信息:

Running activities (most recent first):
      TaskRecord{7259aa1 #168 A=10913:com.test.TestB U=0 StackId=168 sz=2}
        Run #1: ActivityRecord{73c2344 u0 com.silencefly96.fundark/.TestActivityF t168}
        Run #0: ActivityRecord{7327848 u0 com.silencefly96.fundark/.TestActivityD t168}

Running activities (most recent first):
      TaskRecord{7259bab #167 A=10913:com.test.TestA U=0 StackId=167 sz=3}
        Run #2: ActivityRecord{73278c6 u0 com.silencefly96.fundark/.TestActivityC t167}
        Run #1: ActivityRecord{6f69409 u0 com.silencefly96.fundark/.TestActivityB t167}
        Run #0: ActivityRecord{7327983 u0 com.silencefly96.fundark/.TestActivityA t167}

Running activities (most recent first):
      TaskRecord{7259b39 #166 A=10913:com.silencefly96.fundark U=0 StackId=166 sz=1}
        Run #0: ActivityRecord{735a809 u0 com.silencefly96.fundark/.MainActivity t166}

F(new task | clear top | single top) -> B

堆栈信息:

Running activities (most recent first):
      TaskRecord{7259bab #167 A=10913:com.test.TestA U=0 StackId=167 sz=2}
        Run #1: ActivityRecord{6f69409 u0 com.silencefly96.fundark/.TestActivityB t167}
        Run #0: ActivityRecord{7327983 u0 com.silencefly96.fundark/.TestActivityA t167}

Running activities (most recent first):
      TaskRecord{7259aa1 #168 A=10913:com.test.TestB U=0 StackId=168 sz=2}
        Run #1: ActivityRecord{73c2344 u0 com.silencefly96.fundark/.TestActivityF t168}
        Run #0: ActivityRecord{7327848 u0 com.silencefly96.fundark/.TestActivityD t168}

Running activities (most recent first):
      TaskRecord{7259b39 #166 A=10913:com.silencefly96.fundark U=0 StackId=166 sz=1}
        Run #0: ActivityRecord{735a809 u0 com.silencefly96.fundark/.MainActivity t166}

果然又不出所料,TestActivityB复用了,并没有重新创建了,这里就和我们设置singleTask一样了,下面再看下那片文章说的topActivity问题。

测试测试 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP 栈顶复用情况

M(new task) -> A -> B -> C(new task) -> D -> B

堆栈信息:

Running activities (most recent first):
      TaskRecord{70451ab #181 A=10913:com.test.TestB U=0 StackId=181 sz=2}
        Run #1: ActivityRecord{7366d83 u0 com.silencefly96.fundark/.TestActivityB t181}
        Run #0: ActivityRecord{7366d44 u0 com.silencefly96.fundark/.TestActivityD t181}

Running activities (most recent first):
      TaskRecord{7259aa1 #180 A=10913:com.test.TestA U=0 StackId=180 sz=3}
        Run #2: ActivityRecord{6d9a8c6 u0 com.silencefly96.fundark/.TestActivityC t180}
        Run #1: ActivityRecord{6f0a383 u0 com.silencefly96.fundark/.TestActivityB t180}
        Run #0: ActivityRecord{73c2383 u0 com.silencefly96.fundark/.TestActivityA t180}

Running activities (most recent first):
      TaskRecord{7259a55 #179 A=10913:com.silencefly96.fundark U=0 StackId=179 sz=1}
        Run #0: ActivityRecord{71b78c6 u0 com.silencefly96.fundark/.MainActivity t179}

这里我们从栈顶的B,去启动B,用上三个Flag,这里为了区分第一次B跳转,我用了长按跳转的。

B(new task | clear top | single top) -> B

堆栈信息:


Running activities (most recent first):
      TaskRecord{7259aa1 #180 A=10913:com.test.TestA U=0 StackId=180 sz=2}
        Run #1: ActivityRecord{6f0a383 u0 com.silencefly96.fundark/.TestActivityB t180}
        Run #0: ActivityRecord{73c2383 u0 com.silencefly96.fundark/.TestActivityA t180}

Running activities (most recent first):
      TaskRecord{70451ab #181 A=10913:com.test.TestB U=0 StackId=181 sz=2}
        Run #1: ActivityRecord{7366d83 u0 com.silencefly96.fundark/.TestActivityB t181}
        Run #0: ActivityRecord{7366d44 u0 com.silencefly96.fundark/.TestActivityD t181}

Running activities (most recent first):
      TaskRecord{7259a55 #179 A=10913:com.silencefly96.fundark U=0 StackId=179 sz=1}
        Run #0: ActivityRecord{71b78c6 u0 com.silencefly96.fundark/.MainActivity t179}

嗯?说好的复用topActivity呢?当Activity跳转动画不一样的时候我就觉得不对劲了。。这里还是复用了它对应taskAffinity的task,不过我看图里写的是singleTop?下面我又用singleTop试了下。

测试 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | singleTop 栈顶复用情况

M(new task) -> A -> B -> C(new task) -> D -> B

堆栈信息:

Running activities (most recent first):
      TaskRecord{7045113 #186 A=10913:com.test.TestB U=0 StackId=186 sz=2}
        Run #1: ActivityRecord{6d30c87 u0 com.silencefly96.fundark/.TestActivityB t186}
        Run #0: ActivityRecord{6d30d44 u0 com.silencefly96.fundark/.TestActivityD t186}

Running activities (most recent first):
      TaskRecord{70450a1 #185 A=10913:com.test.TestA U=0 StackId=185 sz=3}
        Run #2: ActivityRecord{72cfcc6 u0 com.silencefly96.fundark/.TestActivityC t185}
        Run #1: ActivityRecord{7256e87 u0 com.silencefly96.fundark/.TestActivityB t185}
        Run #0: ActivityRecord{6b0c4c6 u0 com.silencefly96.fundark/.TestActivityA t185}

Running activities (most recent first):
      TaskRecord{7045185 #184 A=10913:com.silencefly96.fundark U=0 StackId=184 sz=1}
        Run #0: ActivityRecord{6f2f7c2 u0 com.silencefly96.fundark/.MainActivity t184}

B(new task | clear top) -> B

堆栈信息:

Running activities (most recent first):
      TaskRecord{70450a1 #185 A=10913:com.test.TestA U=0 StackId=185 sz=2}
        Run #1: ActivityRecord{7256e87 u0 com.silencefly96.fundark/.TestActivityB t185}
        Run #0: ActivityRecord{6b0c4c6 u0 com.silencefly96.fundark/.TestActivityA t185}

Running activities (most recent first):
      TaskRecord{7045113 #186 A=10913:com.test.TestB U=0 StackId=186 sz=2}
        Run #1: ActivityRecord{6d30c87 u0 com.silencefly96.fundark/.TestActivityB t186}
        Run #0: ActivityRecord{6d30d44 u0 com.silencefly96.fundark/.TestActivityD t186}

Running activities (most recent first):
      TaskRecord{7045185 #184 A=10913:com.silencefly96.fundark U=0 StackId=184 sz=1}
        Run #0: ActivityRecord{6f2f7c2 u0 com.silencefly96.fundark/.MainActivity t184}

还是一样的情况啊,那就是说这个topActivity的说法是不对的,FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP三个加起来就和singleTask是一样的。

小结

果然还是不能用博客学东西,需要自己多试试。

你可能感兴趣的:(安卓,android,adb)