Fragment中已废弃startActivityForResult的替换方案及相关疑问咨询
Fragment场景下startActivityForResult废弃适配方案
一、废弃API适配修改方案
AndroidX Activity 1.2.0 和 Fragment 1.3.0 之后官方推出Activity Result API替换已废弃的startActivityForResult(),针对你给出的拍照场景适配步骤如下:
- 移除原来的常量请求码
REQUEST_PHOTO,改用注册启动器的方式接收返回结果 - 在Fragment中提前注册启动器,处理拍照完成后的回调逻辑
- 点击事件中将
startActivityForResult()替换为启动器的launch()方法
修改后完整示例代码
class ExampleFragment:Fragment(), DatePickerFragment.Callbacks { private lateinit var photoUri : Uri // 注册拍照结果启动器 private val takePhotoLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess -> if (isSuccess) { // 这里写原来onActivityResult里REQUEST_PHOTO请求码对应的处理逻辑 // 拍照成功,photoUri里已经有写入的照片数据 } else { // 拍照取消/失败处理 } } override fun onStart() { super.onStart() photoButton.apply { val packageManager : PackageManager = requireActivity().packageManager val captureImage = Intent(MediaStore.ACTION_IMAGE_CAPTURE) val resolvedActivity : ResolveInfo? = packageManager.resolveActivity(captureImage, PackageManager.MATCH_DEFAULT_ONLY) if (resolvedActivity == null) { isEnabled = false } setOnClickListener { val cameraActivities : List<ResolveInfo> = packageManager.queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY) for (cameraActivity in cameraActivities) { requireActivity().grantUriPermission( cameraActivity.activityInfo.packageName,photoUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION ) } // 替换原来的startActivityForResult takePhotoLauncher.launch(photoUri) } } } }
如果你需要自定义Intent而不用封装好的TakePicture契约,也可以用ActivityResultContracts.StartActivityForResult()契约:
// 注册通用启动器 private val customLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val data = result.data // 处理返回结果 } } // 调用时传入自定义intent customLauncher.launch(captureImage)
二、「从Fragment所属宿主Activity调用Activity.startActivityForResult(Intent, int)」的含义
这个描述指的是你在Fragment中不调用Fragment自身的startActivityForResult()方法,而是调用requireActivity().startActivityForResult(intent, requestCode)的写法。
这种写法下,请求的发起方是宿主Activity而非当前Fragment,后续返回结果只会回调到宿主Activity的onActivityResult()方法中,不会分发到当前Fragment的onActivityForResult(),此前这是一个常见的使用误区。
三、简明操作指引
- 确保依赖版本符合要求:项目依赖的AndroidX Fragment版本≥1.3.0,Activity版本≥1.2.0
- 提前注册结果启动器:不要在点击事件等执行逻辑中才注册,必须在Fragment生命周期走到onAttach之前完成注册(直接写在成员变量位置即可)
- 完全替换旧API:废弃的
startActivityForResult()和onActivityResult()直接删除,全逻辑改用Activity Result API - 不要混用发起方:如果需要结果回调到Fragment,永远调用Fragment自身的启动器
launch()方法,不要通过宿主Activity发起页面跳转请求
内容的提问来源于stack exchange,提问作者GreenHelix
相关产品推荐
相关产品推荐

