一给 发表于 2022-6-24 11:36:05

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

背景

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

我们依赖了该library库,然后启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity
val intent = Intent(MainActivity@ this, SecondActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent) 我们打开任务管理器,可以看到如下效果
https://img-blog.csdnimg.cn/f1579880a682405f8476e5c70d4ffe88.jpeg
如果,我们去除该library的依赖,打开任务管理器,就只会有一个"应用"。
或者去除启动Activity时的FLAG_ACTIVITY_NEW_TASK标志,也只会有一个应用。
https://img-blog.csdnimg.cn/45956aeca6de49b093f9135ecee79785.png
原因

后来,排查后,发现和taskAffinity有关。
原来,在该library中,我们在AndroidManifest.xml的Application节点 添加了一个android:taskAffinity="",导致了这个问题。
去掉这个值就不会有这个问题了。
taskAffinity

taskAffinity我们平时很少去用它,它的作用是什么呢 ?
查阅了资料可知
是用于在启动activity时,指定activity放入哪个task (指定想要的任务栈)
官网文档上关于taskAffinity的说明 : https://developer.android.google.cn/guide/topics/manifest/activity-element#lmode
https://img-blog.csdnimg.cn/62a071d7883c4cefbd4b37725b36840c.png
我们来做下试验
试验一

我们保留android:taskAffinity="",启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity,可以看到任务管理器里有3个"应用"
https://img-blog.csdnimg.cn/f1579880a682405f8476e5c70d4ffe88.jpeg
我们使用adb命令,查看下当前Activity栈的信息
adb shelldumpsys 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个"应用"
https://img-blog.csdnimg.cn/45956aeca6de49b093f9135ecee79785.png
我们使用adb命令,查看下当前Activity栈的信息
adb shelldumpsys 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个"应用"
https://img-blog.csdnimg.cn/9831a445d2b54620a9d4caf3d868e692.png
我们使用adb命令,查看下当前Activity栈的信息
adb shelldumpsys 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任务栈里有一个ActivityRecord,taskAffinity为10314:com.heiko.third,
Stack #436任务栈里有两个ActivityRecord,taskAffinity为10314:com.heiko.mytest0614
试验四

我们去除android:taskAffinity="",ThirdActivity的launchMode设置为singleInstance,启动了3个带FLAG_ACTIVITY_NEW_TASK标志位的activity,MainActivity->SecondActivity->ThirdActivity,可以看到任务管理器里有1个"应用"
https://img-blog.csdnimg.cn/45956aeca6de49b093f9135ecee79785.png
我们使用adb命令,查看下当前Activity栈的信息
adb shelldumpsys 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任务栈里有两个ActivityRecord,Stack #434栈中有一个ActivityRecord,且taskAffinity都是10314:com.heiko.mytest0614
小结



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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 解决Android App 每启动一个Activity就看上去多启动一个应用/进程的问题