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

Android(Kotlin) Fragment中CameraX配置相机0超时问题求助

解决CameraX预览超时问题:Unable to configure camera 0, timeout

问题核心原因

你代码里的关键错误是重复创建布局实例,导致CameraX无法获取有效的PreviewView Surface:

  • 在onCreate()中通过FragmentCameraBinding.inflate()创建了一个布局实例,但onCreateView()又返回了另一个通过inflater.inflate()生成的独立布局对象。
  • buildPreviewUseCase()中绑定的binding.cameraPreview并未被添加到Fragment的视图层级中,CameraX无法获取可用的渲染Surface,最终触发超时错误。

修复后的完整代码

package dev.splitsecond.splitsecond_poc

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import dev.splitsecond.splitsecond_poc.databinding.FragmentCameraBinding
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class Camera : Fragment() {
    private lateinit var cameraExecutor: ExecutorService
    private var _binding: FragmentCameraBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        cameraExecutor = Executors.newSingleThreadExecutor()
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentCameraBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        requestRequiredPermissions()
    }

    private fun requestRequiredPermissions() {
        requestCameraPermissionIfMissing { granted ->
            if (granted)
                startCamera()
            else
                Toast.makeText(requireContext(), "请允许相机权限", Toast.LENGTH_LONG).show()
        }
    }

    private fun requestCameraPermissionIfMissing(onResult: ((Boolean) -> Unit)) {
        if (ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            onResult(true)
        } else {
            registerForActivityResult(ActivityResultContracts.RequestPermission()) {
                onResult(it)
            }.launch(Manifest.permission.CAMERA)
        }
    }

    private fun startCamera() {
        val processCameraProvider = ProcessCameraProvider.getInstance(requireContext())
        processCameraProvider.addListener({
            val cameraProvider = processCameraProvider.get()
            val previewUseCase = buildPreviewUseCase()

            cameraProvider.unbindAll()
            cameraProvider.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, previewUseCase)
        }, ContextCompat.getMainExecutor(requireContext()))
    }

    private fun buildPreviewUseCase(): Preview {
        return Preview.Builder().build()
            .also { it.setSurfaceProvider(binding.cameraPreview.surfaceProvider) }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
        cameraExecutor.shutdown()
    }
}

关键修复点

  1. 统一Binding初始化:在onCreateView中初始化Binding并返回binding.root,确保绑定的视图是Fragment实际显示的实例。
  2. 延迟权限请求:将权限请求移到onViewCreated中,保证视图已完全初始化后再启动相机逻辑。
  3. 内存泄漏防护:在onDestroyView中清空Binding引用并关闭相机线程。

内容的提问来源于stack exchange,提问作者Ramon Vermeulen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:45:49