Reputation: 5987
I need to freeze (stop) the preview when user initiates taking the photo. I've searched around and I've found this SO post that mentions unbinding Preview UseCase. I've tried that and at first it works correctly on Android 9+, but on lower Android I receive following error in Logcat and picture is not taken.
ImageCapture: takePictureInternal onFailure
androidx.camera.core.ImageCaptureException: The completer object was garbage collected - this future would otherwise never complete. The tag was: FutureChain[androidx.camera.core.impl.utils.futures.ChainingListenableFuture@3ee79178]
at androidx.camera.core.ImageCapture$ImageCaptureRequest.lambda$notifyCallbackError$1$ImageCapture$ImageCaptureRequest(ImageCapture.java:1911)
at androidx.camera.core.-$$Lambda$ImageCapture$ImageCaptureRequest$1G7WSvt8TANxhZtOyewefm68pg4.run(lambda)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: androidx.concurrent.futures.CallbackToFutureAdapter$FutureGarbageCollectedException: The completer object was garbage collected - this future would otherwise never complete. The tag was: FutureChain[androidx.camera.core.impl.utils.futures.ChainingListenableFuture@3ee79178]
And also a lot of logs starts to appear like
gralloc_ranchu: gralloc_lock usage mismatch usage=0x30 cb->usage=0x3
My suspicion is that the way how I retrieve ProcessCameraProvider
instance is wrong - I just store it once I get from the Future returned from getInstance
method and use it later. But when I tried getting the future again it did not helped. I've found no workaround around this and I am considering replacing CameraX with some other Camera library because I've spent too many time on that but maybe someone has some answer.
I've created a demo project where I test this weird behavior so you can take a look at the full code.
Upvotes: 3
Views: 2188
Reputation: 5987
I've posted this as a bug to Google Issue tracker and this error is intended behavior. To freeze a preview you should not unbind Preview usecase. There may API for that in the future, but currently the recommended way is to store latest frame from ImageAnalysis
and put it to ImageView overlapping the preview.
Upvotes: 3
Reputation: 606
Indeed the solution that I posted in the other post doesn't work with old phones. I tested it on an android 7 and I had the following error:
E/AndroidRuntime: FATAL EXCEPTION: CameraX-camerax_io_0 Process: com.hermosodev.camerax, PID: 23735 java.lang.IllegalStateException: Image is already closed at android.media.Image.throwISEIfImageIsInvalid(Image.java:68) at android.media.ImageReader$SurfaceImage.getFormat(ImageReader.java:679) at androidx.camera.core.AndroidImageProxy.getFormat(AndroidImageProxy.java:78) at androidx.camera.core.ForwardingImageProxy.getFormat(ForwardingImageProxy.java:75) at androidx.camera.core.ForwardingImageProxy.getFormat(ForwardingImageProxy.java:75) at androidx.camera.core.ForwardingImageProxy.getFormat(ForwardingImageProxy.java:75) at androidx.camera.core.ImageUtil.imageToJpegByteArray(ImageUtil.java:51) at androidx.camera.core.ImageSaver.run(ImageSaver.java:95) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761)
With my android 7 when I'm capturing a picture the preview is automatically freezed for a short time before being released (which could explain my error).
What about freezing the preview in the OnImageSavedCallback
?
runOnUiThread {
cameraProvider.unbind(previewUseCase)
}
Upvotes: 0