ActivityResultLauncher在Fragment中使用无报错退后台的问题如何解决?
问题修复方案
核心原因1:Fragment中注册Launcher的时机错误
registerForActivityResult在Fragment中必须在onAttach、onCreate 阶段完成注册,不能在点击事件、onViewCreated之后的生命周期节点注册,也不能延迟到调用时才注册。- 你现有代码将注册放在
populateUI方法中,如果该方法是在Fragment的onViewCreated之后触发,就会导致注册失败,触发隐式闪退。
修复示例:
// 在Fragment的onCreate方法中提前注册 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) registerLauncher() // 把注册逻辑移到这里 }
核心原因2:上下文与API调用适配错误
你贴的是Activity可用的代码,迁移到Fragment时需要修改所有上下文相关调用:
- 权限检查的上下文从
this改为requireContext() shouldShowRequestPermissionRationale调用Fragment自身的方法,不要用Activity的实例- 注册Launcher调用Fragment自身的
registerForActivityResult,不要调用requireActivity().registerForActivityResult
修改后的selectMedia方法示例:
private fun selectMedia() { if (ContextCompat.checkSelfPermission( requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE ) != PackageManager.PERMISSION_GRANTED ) { if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) { Snackbar.make( mBinding!!.root, "需要相册权限才能选择图片", Snackbar.LENGTH_INDEFINITE ).setAction("去授权") { permissionLauncherForGallery.launch(Manifest.permission.READ_EXTERNAL_STORAGE) }.show() } else { permissionLauncherForGallery.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } } else { val intentToGallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) activityResultLauncher.launch(intentToGallery) } }
核心原因3:Android版本权限适配问题
- Android 13(API 33)及以上版本中
READ_EXTERNAL_STORAGE权限已废弃,申请该权限会直接返回拒绝,需要替换为READ_MEDIA_IMAGES权限 - 必须在
AndroidManifest.xml中声明对应权限,否则申请权限会直接闪退:
<!-- 兼容Android 12及以下 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13及以上 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
权限申请时需要根据系统版本动态选择申请的权限:
val requestPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { Manifest.permission.READ_MEDIA_IMAGES } else { Manifest.permission.READ_EXTERNAL_STORAGE } permissionLauncherForGallery.launch(requestPermission)
其他常见问题
- 避免使用
!!强转binding,空状态下会触发空指针异常直接闪退,全部替换为安全调用?. - 跳转相册的Intent部分不需要额外处理
data返回的bitmap,ACTION_PICK返回的就是图片Uri,不需要取extras里的缩略图,强转Bitmap的逻辑如果为空会触发类型转换异常。
内容的提问来源于stack exchange,提问作者Mert DEMIRKIRAN
相关产品推荐
相关产品推荐

