Android:三星A10调用相机startActivityForResult触发未恢复Activity的pause崩溃
崩溃根因
- 这是三星Galaxy A10等搭载Android 9/10系统的入门机型,定制One UI版本存在的已知生命周期调度缺陷,并非业务代码逻辑错误
- 你在Profiler里观察到的「ReportActivity被调用后随即被销毁,之后系统突然触发onPause」的异常序列,完全匹配该缺陷的表现:三星系统在跳转相机时,会提前销毁栈内的ReportActivity,随后又错误地向这个已经销毁、非resumed状态的Activity下发pause回调指令,触发系统层的状态校验抛出RuntimeException
- 故障仅出现在该机型的原因:其他测试机型的系统生命周期状态校验逻辑完全符合AOSP原生规范,不会出现错位的调度指令;两台同型号设备稳定复现也印证了这是固件层面的共性问题,而非偶发环境异常
- 从你贴的调用代码可以看到,启动相机的逻辑是在挂载于ReportActivity下的Fragment中实现的,这会进一步放大系统调度错位的概率:系统在处理Fragment发起的跨Activity跳转时,会更早触发栈内Activity的状态重排流程
针对性修复方案
1. 修正相机启动的调用主体
- 将Fragment中发起相机跳转的代码,从
startActivityForResult(intent, ACTION_TAKE_VIDEO);改为requireActivity().startActivityForResult(intent, ACTION_TAKE_VIDEO); - 该修改的作用是把跨Activity跳转的调度主体从Fragment上移到所属的ReportActivity,避免三星系统针对Fragment跳转的特殊调度逻辑触发状态错位
2. 调整ReportActivity的Manifest配置
在AndroidManifest.xml中找到ReportActivity的配置节点,补充以下参数:
- 设置
launchMode="singleTop",避免系统在跳转时创建重复的Activity实例 - 添加
configChanges="orientation|screenSize|keyboardHidden|uiMode",减少系统在相机跳转过程中对ReportActivity的状态重建、重排流程
3. 系统层异常兜底
该崩溃是系统消息循环层抛出的无效指令,本身不附带任何业务逻辑,可直接针对异常特征做拦截,避免应用崩溃:
- 在自定义Application的
onCreate方法中,添加全局异常拦截逻辑,仅匹配该特定崩溃特征,不影响其他正常异常的处理流程:
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { // 仅拦截三星A10机型的生命周期调度bug if (throwable instanceof RuntimeException && throwable.getMessage() != null && throwable.getMessage().startsWith("Performing pause of activity that is not resumed")) { return; } // 其余异常走原有崩溃上报、提示流程 });
- 该拦截逻辑是安全的:触发异常时的pause指令本身就是系统生成的无效指令,此时ReportActivity已经被系统标记为销毁状态,本身就不需要执行任何pause对应的业务逻辑,拦截后不会造成数据丢失、功能异常,只是阻断了系统错误指令导致的应用崩溃。
验证标准
- 改动完成后,在Galaxy A10设备上重复照片、视频拍摄的全流程,观察Profiler面板的Activity生命周期序列:应呈现正常的
onPause -> onStop -> 相机返回后 onStart -> onResume的流程,不会出现ReportActivity销毁后被系统触发pause的异常序列 - 其余测试机型的功能、运行逻辑不受改动影响
内容的提问来源于stack exchange,提问作者Rubén Gómez
相关产品推荐
相关产品推荐

