CameraX is supposed to be the "easy" camera API, but developers still run into the dreaded "Black Preview" screen. This usually isn't a bug in the library, but a mismatch in lifecycle or surface binding.
SurfaceProvider Binding
Ensure you're binding your Preview use case to the PreviewView correctly.
If you call setSurfaceProvider too late or on the wrong thread, the surface won't
initialize, resulting in a black screen.
val preview = Preview.Builder().build()
preview.setSurfaceProvider(previewView.surfaceProvider)
Handling Aspect Ratio
A black screen can also occur if the system can't find a resolution that matches your requested
aspect ratio. Instead of forcing a specific resolution, use setTargetAspectRatio to let
CameraX choose the best fit for the device hardware.
val imageCapture = ImageCapture.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build()
The Golden Rule
Always unbind all use cases before re-binding them (e.g., during a camera switch). If you try to bind multiple camera instances to the same provider, the system will prioritize the first one, leaving the second one blank.
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview, imageCapture)
Summary
CameraX is lifecycle-aware, but you still need to manage your surface providers and aspect ratios. Clear your use cases before re-binding, and your previews will always be bright!