简体   繁体   English

CameraX - 解除绑定预览用例时崩溃

[英]CameraX - crash when unbinding Preview UseCase

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.我四处搜索,发现这个SO 帖子提到了取消绑定预览用例。 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.我已经尝试过了,起初它可以在 Android 9+ 上正常工作,但是在较低的 Android 上,我在 Logcat 中收到以下错误并且没有拍照。

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.我怀疑我检索ProcessCameraProvider实例的方式是错误的 - 一旦我从getInstance方法返回的 Future 获取并稍后使用它,我就存储它。 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.我没有找到解决这个问题的方法,我正在考虑用其他一些相机库替换 CameraX,因为我在这方面花了太多时间,但也许有人有一些答案。

I've created a demo project where I test this weird behavior so you can take a look at the full code.我已经创建了一个演示项目,我在其中测试了这种奇怪的行为,因此您可以查看完整的代码。

I've posted this as a bug to Google Issue tracker and this error is intended behavior.我已将此作为错误发布到Google 问题跟踪器,此错误是预期行为。 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.将来可能会有 API,但目前推荐的方法是存储来自ImageAnalysis最新帧并将其放入与预览重叠的 ImageView。

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:我在 android 7 上对其进行了测试,但出现以下错误:

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) E/AndroidRuntime:致命异常:CameraX-camerax_io_0 进程:com.hermosodev.camerax,PID:23735 java.lang.IllegalStateException:图像已在 android.media.Image.throwISEIfImageIsInvalid(Image.java:68) 的 android.media 处关闭.ImageReader$SurfaceImage.getFormat(ImageReader.java:679) 在 androidx.camera.core.AndroidImageProxy.getFormat(AndroidImageProxy.java:78) 在 androidx.camera.core.ForwardingImageProxy.getFormat(ForwardingImageProxy.java:75) 在 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) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) ) 在 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).使用我的 android 7 拍摄图片时,预览会在发布前自动冻结一小段时间(这可以解释我的错误)。

What about freezing the preview in the OnImageSavedCallback ?OnImageSavedCallback冻结预览怎么样?

runOnUiThread {
   cameraProvider.unbind(previewUseCase)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM