react-native-vision-camera icon indicating copy to clipboard operation
react-native-vision-camera copied to clipboard

fix: App crashes when Camera using scanner is closed

Open Hector-Chong opened this issue 1 year ago • 10 comments

What

The App crashes when the Camera component with the code scanner after returning results is closed and unmounted.

Changes

The PR changes the destroyPreviewOutputSync and makes it run within the main dispatcher.

Tested on

OPPO A36, Android 11

Related issues

  • Fixes #2189

Note

I'm 100% sure this is the correct solution, but it works for me and others. I have not fully tested other features except for code scanner and photo capture which satisfy my needs, so I have not further debugged either.

What's more, I have another solution. This function aims to let configure compare out a difference, and forcing diff to be true can also resolve this issue. So that,

  suspend fun configure(lambda: (configuration: CameraConfiguration) -> Unit) {
    mutex.withLock {
      Log.i(TAG, "Updating CameraSession Configuration...")

      val config = CameraConfiguration.copyOf(this.configuration)
      lambda(config)
//      val diff = CameraConfiguration.difference(this.configuration, config)
      val diff = CameraConfiguration.Difference(true, true, true);

Of course, this is a more inappropriate solution, but just to give a clue of what's going on here.

Let me know if you need another PR or more information

Hector-Chong avatar Nov 25 '23 01:11 Hector-Chong

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-native-vision-camera ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 25, 2023 1:32am

vercel[bot] avatar Nov 25 '23 01:11 vercel[bot]

and forcing diff to be true can also resolve this issue

Interesting, maybe the true fix can be in Difference? I'll take a look soon, thanks for your PR!

mrousavy avatar Nov 27 '23 12:11 mrousavy

destroyPreviewOutputSync

and forcing diff to be true can also resolve this issue

Interesting, maybe the true fix can be in Difference? I'll take a look soon, thanks for your PR!

If destroyPreviewOutputSync is called that means outputsChanged and sidePropsChanged must be true inside CameraConfiguration.difference, but deviceChanged not not be so, as a result, configureCameraDevice is not called. However, it does not make sense to me a little that forcing this function running on main thread can resolve this issue.

Hector-Chong avatar Nov 28 '23 09:11 Hector-Chong

Yea, the problem with the Main Thread approach is that this queues the stop to be run on the Main Thread. The method destroyPreviewOutputSync() already returns, which tells Android "hey, you can now safely delete the SurfaceView".

So assuming Android deletes the SurfaceView now, and we still try to draw a Frame to it BEFORE the launch(Dispatchers.Main) { has actually executed, we are drawing to a deleted Surface, which will crash.

We need to be aware that this race condition can exist, so I think a true fix is to provide a single source of truth for the Difference and delete the Preview accordingly, I will take a look at that soon!

I think running this fix in your app for now is perfectly fine though, that's like a 0.001% chance of crashing.

mrousavy avatar Nov 28 '23 19:11 mrousavy

@mrousavy thank you in advance! Any update on this?

BrechtBD avatar Dec 04 '23 07:12 BrechtBD

Are there updates regarding this PR?

mare95 avatar Dec 06 '23 12:12 mare95

Facing the same issue.

Sharf8351 avatar Dec 13 '23 09:12 Sharf8351

same problem here

gabrielsalvi avatar Jan 09 '24 19:01 gabrielsalvi

I think I'm having this same problem. I'm scanning QR codes on an app. And sometimes after scanning the app will crash with a seg fault.

I've patched these changes into my project and can confirm its stopped crashing

Gambitboy avatar Mar 06 '24 11:03 Gambitboy

I got the same issue, looking forward to the merge of this PR. Thanks for your good work!

mschmid avatar Apr 15 '24 15:04 mschmid