Skip to content

Fix detectCharset ANR#12

Closed
kreativityapps wants to merge 1 commit into
amake:masterfrom
kreativityapps:fix_detectCharset_anr
Closed

Fix detectCharset ANR#12
kreativityapps wants to merge 1 commit into
amake:masterfrom
kreativityapps:fix_detectCharset_anr

Conversation

@kreativityapps
Copy link
Copy Markdown

There are a couple of ANR's in Google Play Console:

      at org.mozilla.universalchardet.prober.SingleByteCharsetProber.f (SingleByteCharsetProber.java:2)
      at org.mozilla.universalchardet.prober.SBCSGroupProber.handleData (SBCSGroupProber.java:148)
      at org.mozilla.universalchardet.UniversalDetector.handleData (UniversalDetector.java:222)
      at org.mozilla.universalchardet.UniversalDetector.detectCharset (UniversalDetector.java:383)
      at com.madlonkay.flutter_charset_detector.FlutterCharsetDetectorPlugin.handleAutoDecode (FlutterCharsetDetectorPlugin.kt:38)
      at com.madlonkay.flutter_charset_detector.FlutterCharsetDetectorPlugin.onMethodCall (FlutterCharsetDetectorPlugin.kt:26)
      at io.flutter.plugin.common.MethodChannel$IncomingMethodCa
      at io.flutter.embedding.engine.dart.DartMessenger.invokeHandle
      at io.flutter.embedding.engine.dart.DartMessenger.lambda$disp
      at android.os.Handler.handleCallback (Handler.java:942)
      at android.os.Handler.dispatchMessage (Handler.java:99)
      at android.os.Looper.loopOnce (Looper.java:201)
      at android.os.Looper.loop (Looper.java:288)
      at android.app.ActivityThread.main (ActivityThread.java:7941)
      at java.lang.reflect.Method.invoke (Native method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:569)
      at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)

This change fixes the ANR caused by blocking the UI thread.

@amake
Copy link
Copy Markdown
Owner

amake commented Jul 3, 2025

Thanks for this. I haven't seen detectCharset take a significant amount of time (only the first few bytes are inspected in many cases), but I imagine there are inputs that take longer than others. Do you have an idea what kinds of inputs you have that are taking so long?

Also, I am aware that there is a preference for coroutines over threads in Kotlin. Is there a reason you chose threads instead of coroutines?

@kreativityapps
Copy link
Copy Markdown
Author

Hi, I saw these ANR's only in the crash logs, I don't have the input which triggered them. Locally is fast also for me.
I can use coroutines if you prefer, no problem, let me know.

@amake
Copy link
Copy Markdown
Owner

amake commented Jul 11, 2025

Sorry for the delay on this. Here's what's going on:

My intuition is that detecting the charset itself is quite fast, so I wanted to reproduce this issue for myself to see exactly where the bottlenecks are. I did the following:

  1. Modified the example app to include a CircularProgressIndicator so I could see when the UI thread was blocked
  2. Modified the example app to detect the charset of the default asset file * 1000
  3. Put timing logs all over the place
  4. Compared the current implementation with an implementation where the detection (and decoding) is done on a separate thread (I mainly work on iOS so I used a DispatchQueue.global(qos: .userInitiated))

With a large payload, I see the UI is blocked for about 1.2s on my device, but it seems like all of that is transmitting the payload over the MethodChannel and not the work done by the detector. but this turned out to be me measuring entirely the wrong thing.

Then I thought, "why not eliminate the MethodChannel entirely by reimplementing this plugin as a direct FFI interface for uchardet"? So I'm partway through figuring out how to do that. But then I realized that we still need the decoding part, which is not covered by uchardet, and would still require a MethodChannel to use the platform's decoding features (unless there's a way to use that via FFI as well).

I recognize that the Android implementation is entirely different (juniversalchardet in Java), so I will see if your change makes a material difference on my Android device.

@amake
Copy link
Copy Markdown
Owner

amake commented Jul 11, 2025

Can you check #13 to see if it addresses your issue? Or at least looks like it should?

@kreativityapps
Copy link
Copy Markdown
Author

Thank you, it looks good to me.

@amake
Copy link
Copy Markdown
Owner

amake commented Jul 11, 2025

Equivalent changes are now released in flutter_charset_detector_android v3.1.0

@amake amake closed this Jul 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants