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() } }
关键修复点
- 统一Binding初始化:在
onCreateView中初始化Binding并返回binding.root,确保绑定的视图是Fragment实际显示的实例。 - 延迟权限请求:将权限请求移到
onViewCreated中,保证视图已完全初始化后再启动相机逻辑。 - 内存泄漏防护:在
onDestroyView中清空Binding引用并关闭相机线程。
内容的提问来源于stack exchange,提问作者Ramon Vermeulen
相关产品推荐
相关产品推荐

