SingleTask启动模式下通过DeepLink跳转ActivityB时Back Stack清空、ActivityA销毁的原因排查求助
分析SingleTask启动模式下DeepLink跳转导致ActivityA销毁的原因
首先,咱们得抓住两种跳转流程的核心差异:启动Intent的来源和系统附加的标记,再结合SingleTask启动模式的特性来拆解问题。
先理清楚两种流程的任务栈行为
流程1:应用内部显式跳转(正常返回)
你从ActivityA(SingleTask)显式启动ActivityB(SingleTask)时,这个Intent是来自应用内部的,系统不会附加FLAG_ACTIVITY_NEW_TASK标记。因为两个Activity的taskAffinity默认都是应用包名(你没单独修改的话),所以ActivityB会直接被压入ActivityA所在的任务栈,最终栈结构是 [ActivityA, ActivityB]。按下返回键时,ActivityB出栈,回到ActivityA,完全符合预期。
流程2:DeepLink隐式跳转(ActivityA被销毁)
通过DeepLink启动ActivityB时,这个Intent是由系统的DeepLink解析器触发的,属于外部启动,系统会自动给Intent加上FLAG_ACTIVITY_NEW_TASK标记。这时候SingleTask的特性就会和这个标记产生特殊交互:
任务栈匹配与创建
系统会先查找是否存在与ActivityB的taskAffinity匹配的任务栈:- 如果ActivityB和ActivityA的
taskAffinity相同:理论上系统会把ActivityA所在的任务栈带到前台,再把ActivityB压入栈顶,栈结构应该还是[ActivityA, ActivityB]。但你遇到ActivityA被销毁,大概率是这两个隐藏配置在搞鬼:- ActivityA设置了
android:finishOnTaskLaunch="true":这个属性的作用是,当ActivityA所在的任务栈被切换到后台(ActivityB的任务栈成为前台),ActivityA会被自动finish销毁。 - 系统额外附加了
FLAG_ACTIVITY_CLEAR_TOP:部分场景下,DeepLink的Intent会被系统加上这个标记。如果栈里没有ActivityB的实例,系统会创建ActivityB,同时清空栈中所有在它之上的Activity——不过这里ActivityA在栈底,这个可能性较低,但可以排查。
- ActivityA设置了
- 如果ActivityB的
taskAffinity被你单独修改成了和ActivityA不同的值:系统会为ActivityB创建一个全新的任务栈,此时ActivityA所在的原任务栈会被挤到后台。如果你的设备内存紧张,系统会优先销毁后台任务栈里的ActivityA;当你按下返回键,ActivityB出栈后,新任务栈为空,应用直接退出,而原任务栈的ActivityA已经被销毁了。
- 如果ActivityB和ActivityA的
SingleTask的外部启动特性
当从外部启动SingleTask模式的Activity时,系统会默认把它作为新任务的根Activity。这种情况下,原任务栈中的ActivityA如果没有其他前台组件支撑,很容易被系统的任务管理策略销毁,尤其是在应用后台资源受限的时候。
验证与解决方法
- 先检查两个Activity的
taskAffinity配置,确保它们一致(默认就是应用包名,不要单独给ActivityB设置不同的值)。 - 查看ActivityA的Manifest配置,有没有
android:finishOnTaskLaunch="true"或android:clearTaskOnLaunch="true"这两个属性,如果有,去掉试试。 - 可以通过
adb shell dumpsys activity activities命令打印任务栈结构,对比两种流程下的栈差异,直接确认ActivityA是否被压入栈中或者被销毁。 - 如果允许的话,在启动DeepLink的Intent中手动移除
FLAG_ACTIVITY_NEW_TASK标记,看是否能保留ActivityA的栈结构。
内容的提问来源于stack exchange,提问作者Vikram Ragu
相关产品推荐
相关产品推荐

