Android registerForActivityResult启动器销毁重建后无法接收返回结果求助
问题排查与解决步骤
1. 测试方式有效性说明
你使用开发者选项「Don't keep activities」测试的方式完全正确,这是官方推荐的模拟低内存下系统销毁后台Activity场景的标准手段,和实际用户设备上的低内存销毁行为完全一致。官方文档的测试章节就是为了提醒开发者覆盖这类极端场景,避免线上出现仅在低内存下才会触发的问题。
2. 核心问题定位
你当前的问题核心是多余的手动注销操作:
你在第一个Activity的onDestroy生命周期中调用了scanQr.unregister(),这个操作完全不需要,甚至是问题的诱因。AndroidX的ComponentActivity(AppCompatActivity的父类)已经自动实现了Activity Result启动器的生命周期管理,会在实例销毁时自动注销旧实例的启动器,不需要开发者手动操作。
当开启「Don't keep activities」时,你跳转到第二个Activity后,第一个Activity的旧实例就会被销毁,此时你手动调用的unregister()会提前解绑回调链路,重建后的新实例无法正常接收到系统返回的结果。
3. 修复方案
- 第一步:删除第一个Activity
onDestroy方法中scanQr.unregister()的调用 - 第二步:确认你的项目依赖版本满足要求:
androidx.activity:activity-ktx版本≥1.2.0,androidx.fragment:fragment-ktx版本≥1.3.0,这是Activity Result API稳定运行的最低版本要求 - 第三步:建议给回调增加结果校验逻辑,避免后续处理异常,示例如下:
private val scanQr = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> if (result.resultCode == Activity.RESULT_OK) { val qrCode = result.data?.getStringExtra(EXTRA_QR_CODE).orEmpty() Toast.makeText(this, "Result obtained: $qrCode", Toast.LENGTH_SHORT).show() } }
按以上步骤修改后,销毁重建场景下的回调就能正常触发了。
内容的提问来源于stack exchange,提问作者ghevin
相关产品推荐
相关产品推荐

