对 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_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK
如果同时在加上FLAG_ACTIVITY_SINGLE_TOP,会更特殊一些,如果topActivity不是目标Activity,就会去目标Task中去找,并唤起:
FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK| singleTop
如果topActivity是目标Activity,就直接回调topActivity的onNewIntent,无论topActivity是不是在目标Task中
FLAG_ACTIVITY_CLEAR_TOP| FLAG_ACTIVITY_NEW_TASK| singleTop
纸上得来终觉浅,绝知此事要躬行,下面我们就来试试,是不是和这篇文章说的一样。
准备工作
这里需要准备一些东西:代码、测试手机、adb命令。
代码其实很简单,只要创建A、B、C、D、E五个Activity,对它们设置不同的taskAffinity(这里taskAffinity居然还有格式要求),然后启动他们,如果要新开栈,需要配合FLAG_ACTIVITY_NEW_TASK跳转。
<activity android:name=".TestActivityA" android:taskAffinity="com.test.TestA"/>
<activity android:name=".TestActivityB" android:taskAffinity="com.test.TestA"/>
<activity android:name=".TestActivityC" android:taskAffinity="com.test.TestA"/>
<activity android:name=".TestActivityD" android:taskAffinity="com.test.TestB"/>
<activity android:name=".TestActivityE" android:taskAffinity="com.test.TestB"/>
测试手机我这用的荣耀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是一样的。
小结
果然还是不能用博客学东西,需要自己多试试。