You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android复用相机相册类报错:LifecycleOwner注册时机异常

解决LifecycleOwner处于RESUMED状态时注册观察者的异常问题

问题原因

你遇到的IllegalStateException是因为Lifecycle观察者的注册时机太晚:当Fragment已经进入RESUMED状态(比如在点击事件回调中注册),Lifecycle框架禁止在此阶段注册观察者,要求必须在STARTED状态之前(即CREATED阶段,比如onCreate、onViewCreated方法中)完成注册。

解决方案

核心思路是将工具类的初始化和Lifecycle观察者注册提前到Fragment的早期生命周期阶段,而不是在用户交互(如点击事件)时才执行。同时调整工具类的设计,让它在构造时就绑定LifecycleOwner并完成必要的注册。

1. 调整GalleryAndCamera工具类

修改工具类,通过构造参数接收LifecycleOwner,并在构造阶段完成Lifecycle观察者和ActivityResultLauncher的注册(如果涉及拍照/相册的Activity结果处理):

import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.activity.result.ActivityResultContracts
import androidx.activity.result.registerForActivityResult

class GalleryAndCamera(private val lifecycleOwner: LifecycleOwner) {
    // 拍照结果回调
    private val takePhotoLauncher = lifecycleOwner.registerForActivityResult(
        ActivityResultContracts.TakePicturePreview()
    ) { bitmap ->
        // 处理拍照得到的Bitmap
        bitmap?.let { /* 你的业务逻辑 */ }
    }

    // 相册选择结果回调
    private val pickGalleryLauncher = lifecycleOwner.registerForActivityResult(
        ActivityResultContracts.GetContent()
    ) { uri ->
        // 处理选中的图片URI
        uri?.let { /* 你的业务逻辑 */ }
    }

    init {
        // 注册Lifecycle观察者,用于清理资源
        lifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onDestroy(owner: LifecycleOwner) {
                // 在这里释放工具类占用的资源,比如关闭相机、清空缓存等
                super.onDestroy(owner)
            }
        })
    }

    // 对外暴露的拍照方法
    fun startTakePhoto() {
        takePhotoLauncher.launch(null)
    }

    // 对外暴露的相册选择方法
    fun startPickFromGallery() {
        pickGalleryLauncher.launch("image/*")
    }
}

2. 在Fragment中正确调用工具类

在Fragment的onViewCreated(或onCreate)方法中初始化工具类,此时Fragment处于CREATED状态,符合Lifecycle的注册要求:

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment

class MyFragment : Fragment() {
    private lateinit var galleryAndCamera: GalleryAndCamera

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 提前初始化工具类,绑定当前Fragment作为LifecycleOwner
        galleryAndCamera = GalleryAndCamera(this)

        // 点击事件仅触发操作,不再处理注册逻辑
        binding.btnTakePhoto.setOnClickListener {
            galleryAndCamera.startTakePhoto()
        }

        binding.btnPickGallery.setOnClickListener {
            galleryAndCamera.startPickFromGallery()
        }
    }
}

关键注意点

  • ActivityResultLauncher的注册时机:如果你的工具类使用registerForActivityResult处理拍照/相册结果,同样必须在LifecycleOwner处于CREATED状态时完成注册,否则会抛出相同的异常。
  • 资源清理:通过LifecycleObserver的onDestroy方法,在Fragment销毁时清理工具类占用的资源,避免内存泄漏。
  • 复用性保证:工具类通过构造参数接收LifecycleOwner,确保可以在任意Fragment中复用,无需修改核心逻辑。

内容的提问来源于stack exchange,提问作者Erik Orosz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:47:39