解决Android App 每启动一个Activity就看上去多启动一个应用/进程的问题

背景

出现一个很神奇的问题,集成了一个library依赖后,每启动一个FLAG_ACTIVITY_NEW_TASK标志位的Activity就会在任务管理器中多一个"应用"。
如果去除这个library依赖,则无论启动多少个带FLAG_ACTIVITY_NEW_TASK标志位的Activity,任务管理器中永远都只有这一个"应用"。

重现步骤

我们依赖了该library库,然后启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activityMainActivity->SecondActivity->ThirdActivity

val intent = Intent(MainActivity@ this, SecondActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)

我们打开任务管理器,可以看到如下效果
在这里插入图片描述
如果,我们去除该library的依赖,打开任务管理器,就只会有一个"应用"。
或者去除启动Activity时的FLAG_ACTIVITY_NEW_TASK标志,也只会有一个应用
在这里插入图片描述

原因

后来,排查后,发现和taskAffinity有关。

原来,在该library中,我们在AndroidManifest.xmlApplication节点 添加了一个android:taskAffinity="",导致了这个问题。
去掉这个值就不会有这个问题了。

taskAffinity

taskAffinity我们平时很少去用它,它的作用是什么呢 ?

查阅了资料可知
是用于在启动activity时,指定activity放入哪个task (指定想要的任务栈)

官网文档上关于taskAffinity的说明 : https://developer.android.google.cn/guide/topics/manifest/activity-element#lmode
在这里插入图片描述
我们来做下试验

试验一

我们保留android:taskAffinity="",启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity,可以看到任务管理器里有3个"应用"
在这里插入图片描述
我们使用adb命令,查看下当前Activity栈的信息

adb shell  dumpsys activity activities

我们搜索Stack #,可以看到如下信息

  Stack #384: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mLastPausedActivity: ActivityRecord{18aa8f u0 com.heiko.mytest0614/.ThirdActivity t384}
    * Task{812611c #384 visible=true type=standard mode=fullscreen translucent=true I=com.heiko.mytest0614/.ThirdActivity U=0 StackId=384 sz=1}
      ...省略...
	  taskAffinity=null
	  ...省略...

  Stack #383: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mLastPausedActivity: ActivityRecord{84c8851 u0 com.heiko.mytest0614/.SecondActivity t383}
    * Task{9c4e8b6 #383 visible=true type=standard mode=fullscreen translucent=true I=com.heiko.mytest0614/.SecondActivity U=0 StackId=383 sz=1}
      ...省略...
	  taskAffinity=null
	  ...省略...

  Stack #382: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mLastPausedActivity: ActivityRecord{c88411e u0 com.heiko.mytest0614/.MainActivity t382}
    * Task{50f0dff #382 visible=true type=standard mode=fullscreen translucent=true I=com.heiko.mytest0614/.MainActivity U=0 StackId=382 sz=1}
	  ...省略...
      taskAffinity=null
	  ...省略...

com.heiko.mytestApp项目,拥有3个任务栈,且taskAffinity都是null

试验二

我们去除android:taskAffinity="",启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity,可以看到任务管理器里有1个"应用"
在这里插入图片描述
我们使用adb命令,查看下当前Activity栈的信息

adb shell  dumpsys activity activities

我们搜索Stack #,可以看到如下信息

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #424: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mResumedActivity: ActivityRecord{66c8f u0 com.heiko.mytest0614/.ThirdActivity t424}
    mLastPausedActivity: ActivityRecord{66c8f u0 com.heiko.mytest0614/.ThirdActivity t424}
    * Task{813f21d #424 visible=true type=standard mode=fullscreen translucent=true A=10314:com.heiko.mytest0614 U=0 StackId=424 sz=3}
      ...省略
 supportsSplitScreenWindowingMode=true      lastActiveTime=1806671486 (inactive for 7s)
 pcFlags 0      * Hist #2: ActivityRecord{66c8f u0 com.heiko.mytest0614/.ThirdActivity t424}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...
      * Hist #1: ActivityRecord{7a80a7 u0 com.heiko.mytest0614/.SecondActivity t424}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...
      * Hist #0: ActivityRecord{870bb65 u0 com.heiko.mytest0614/.MainActivity t424}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...

com.heiko.mytestApp项目,拥有1个任务栈,这个栈里有三个ActivityRecord,且taskAffinity都是10314:com.heiko.mytest0614

试验三

我们去除android:taskAffinity="",ThirdActivity的taskAffinity设置为com.heiko.third,启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity,可以看到任务管理器里有2个"应用"

在这里插入图片描述
我们使用adb命令,查看下当前Activity栈的信息

adb shell  dumpsys activity activities

我们搜索Stack #,可以看到如下信息

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #437: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mResumedActivity: ActivityRecord{2d1e033 u0 com.heiko.mytest0614/.ThirdActivity t437}
    * Task{1e2ff0 #437 visible=true type=standard mode=fullscreen translucent=true A=10314:com.heiko.third U=0 StackId=437 sz=1}
      ...省略...
 supportsSplitScreenWindowingMode=true      lastActiveTime=1807455552 (inactive for 2s)
 pcFlags 0      * Hist #0: ActivityRecord{2d1e033 u0 com.heiko.mytest0614/.ThirdActivity t437}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.third
          ...省略...

  Stack #436: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mLastPausedActivity: ActivityRecord{2197e45 u0 com.heiko.mytest0614/.SecondActivity t436}
    * Task{2384575 #436 visible=true type=standard mode=fullscreen translucent=true A=10314:com.heiko.mytest0614 U=0 StackId=436 sz=2}
      ...省略...
 supportsSplitScreenWindowingMode=true      lastActiveTime=1807455438 (inactive for 2s)
 pcFlags 0      * Hist #1: ActivityRecord{2197e45 u0 com.heiko.mytest0614/.SecondActivity t436}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...
      * Hist #0: ActivityRecord{bfa74ac u0 com.heiko.mytest0614/.MainActivity t436}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...

com.heiko.mytestApp项目,拥有2个任务栈。
Stack #437任务栈里有一个ActivityRecordtaskAffinity10314:com.heiko.third
Stack #436任务栈里有两个ActivityRecordtaskAffinity10314:com.heiko.mytest0614

试验四

我们去除android:taskAffinity="",ThirdActivity的launchMode设置为singleInstance,启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity,可以看到任务管理器里有1个"应用"
在这里插入图片描述
我们使用adb命令,查看下当前Activity栈的信息

adb shell  dumpsys activity activities

我们搜索Stack #,可以看到如下信息

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #434: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mResumedActivity: ActivityRecord{e1a6f04 u0 com.heiko.mytest0614/.ThirdActivity t434}
    * Task{2caced #434 visible=true type=standard mode=fullscreen translucent=true A=10314:com.heiko.mytest0614 U=0 StackId=434 sz=1}
      ...省略...
 pcFlags 0      * Hist #0: ActivityRecord{e1a6f04 u0 com.heiko.mytest0614/.ThirdActivity t434}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...
		  
		  
Stack #433: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
    mLastPausedActivity: ActivityRecord{8551b41 u0 com.heiko.mytest0614/.SecondActivity t433}
    * Task{4450b31 #433 visible=true type=standard mode=fullscreen translucent=true A=10314:com.heiko.mytest0614 U=0 StackId=433 sz=2}
      ...省略...
 supportsSplitScreenWindowingMode=true      lastActiveTime=1807157149 (inactive for 2s)
 pcFlags 0      * Hist #1: ActivityRecord{8551b41 u0 com.heiko.mytest0614/.SecondActivity t433}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...
      * Hist #0: ActivityRecord{ec9ff65 u0 com.heiko.mytest0614/.MainActivity t433}
          packageName=com.heiko.mytest0614 processName=com.heiko.mytest0614
          ...省略...
          taskAffinity=10314:com.heiko.mytest0614
          ...省略...

com.heiko.mytestApp项目,拥有2个Activity栈,Stack #433任务栈里有两个ActivityRecordStack #434栈中有一个ActivityRecord,且taskAffinity都是10314:com.heiko.mytest0614

小结

  • taskAffinity的不同,直观的表现是在任务管理器里,以不同的"应用"来体现
  • 微信的每一个小程序,都在任务管理器里单独显示,也是用到了taskAffinity
  • taskAffinity一样的Activity具有同一任务 (从用户的角度来看,则是归属同一"应用")
  • 默认情况下,应用中的所有 Activity的taskAffinity 都一样,为应用的包名
  • 如要要指定 Activity 与任何任务都不一样,需将其设置为空字符串
  • 不仅可以给同一个应用的不同activity设置不同的affinity,也可以给不同应用的activity设置相同的affinity,使它们在用户角度看来好像属于同一个应用
  • 当启动模式设置为 standardsingleTop 时,taskAffinity是不起作用的,待启动的 Activity 会跟随 源Activity 的任务栈,即使你显式声明了不一样的 taskAffinity
  • 当启动模式设置了 singleTask 或者 singleInstance 时,它就会新建任务栈来存储待启动的 Activity 实例
  • 除了 singleTasksingleInstance 以外,FLAG_ACTIVITY_NEW_TASK 也会使 taskAffinity 生效

在不设置 taskAffinity 的情况下,单独设置 FLAG_ACTIVITY_NEW_TASK 并没有任何意义,不会创建新的任务栈
FLAG_ACTIVITY_NEW_TASK 更被大家所熟知的用法可能是 从非 Activity 环境启动 Activity 。
默认情况下,待启动的 Activity 会进入源 Activity 所在的任务栈中。如果是从 非 Activity 环境启动,例如 Service,Broadcast,Application 等,根本不存在与之对应的任务栈,AMS 无从推断该把 Activity 放入哪个任务栈,就会抛出异常 Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag

对于非 Activity 启动的 Activity需要显示的设置 FLAG_ACTIVITY_NEW_TASK,而singleTask 及 singleInstance 在 AMS 中被预处理后,隐形的设置了 FLAG_ACTIVITY_NEW_TASK,而启动模式是 standard 及 singletTop 的 Activity 不会被设置 FLAG_ACTIVITY_NEW_TASK,除非通过显式的 Intent setFlag() 进行设置。
FLAG_ACTIVITY_NEW_TASK 这个属性更多的关注点是在 Task,可以认为没有设置 FLAG_ACTIVITY_NEW_TASK 的情况下,taskAffinity 可以不考虑。

其他

参考
Android Task 相关
任务栈?返回栈?启动模式?
面试官装x失败之:Activity的启动模式
taskAffinity的使用
Android Developer-Activity

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

氦客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值