如何修复横屏模式启动TakePicture时Fragment的未注册ActivityResultLauncher异常?
修复横屏模式下Fragment中ActivityResultLauncher未注册异常
这个异常的核心原因是横屏切换导致Fragment重建后,原有的ActivityResultLauncher已失效,但代码仍在调用旧Launcher的launch方法。以下是针对性的修复方案:
在Fragment的
onCreate生命周期中注册Launcher
不要在onViewCreated或更晚的生命周期注册,因为横屏重建时onCreate会重新执行,能保证每次重建都生成有效的Launcher实例。示例代码:private lateinit var takePictureLauncher: ActivityResultLauncher<Uri> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 注册拍照用的Launcher takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess -> if (isSuccess) { // 处理拍照成功后的逻辑 } } }注意:
registerForActivityResult必须在Fragment进入STARTED状态前调用,onCreate是最安全的时机。禁止序列化保存Launcher
ActivityResultLauncher不支持序列化,不要尝试将其存入savedInstanceState,每次Fragment重建时重新注册即可。确保调用launch的时机合法
只在Fragment处于活跃状态时调用takePictureLauncher.launch(uri),比如绑定在按钮点击事件、用户主动触发的交互中,避免在Fragment未初始化或已销毁时调用。恢复横屏重建后的拍照临时Uri
如果拍照使用了临时Uri(比如通过FileProvider生成),需要在onSaveInstanceState中保存Uri,重建后在onCreate中恢复,避免Uri失效:private var tempPhotoUri: Uri? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 恢复之前保存的Uri,没有则重新生成 tempPhotoUri = savedInstanceState?.getParcelable("TEMP_PHOTO_URI") ?: createTempPhotoUri() // 注册Launcher... } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putParcelable("TEMP_PHOTO_URI", tempPhotoUri) } private fun createTempPhotoUri(): Uri { // 生成临时图片Uri的示例逻辑 val tempFile = File(requireContext().cacheDir, "temp_capture.jpg") return FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.fileprovider", tempFile) }
内容的提问来源于stack exchange,提问作者Gkapoor
相关产品推荐
相关产品推荐

