Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Probable deadlock detected due to WebView API being called on incorrect thread while the UI thread is blocked #2806

Closed
medonagy45 opened this issue Jan 13, 2023 · 9 comments

Comments

@medonagy45
Copy link

Hi,
I am getting a crash report on production
I don't know how to reproduce

Exception java.lang.IllegalStateException:
at com.facebook.react.bridge.ReactContext.handleException (ReactContext.java:429)
at com.facebook.react.bridge.ReactContext$ExceptionHandlerWrapper.handleException (ReactContext.java:436)
at com.facebook.react.bridge.GuardedRunnable.run (GuardedRunnable.java:32)
at android.os.Handler.handleCallback (Handler.java:900)
at android.os.Handler.dispatchMessage (Handler.java:103)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
at android.os.Looper.loop (Looper.java:219)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:228)
at java.lang.Thread.run (Thread.java:929)
Caused by java.lang.RuntimeException: Probable deadlock detected due to WebView API being called on incorrect thread while the UI thread is blocked.
at cB0.c (cB0.java:47)
at com.android.webview.chromium.WebViewChromiumFactoryProvider.h (WebViewChromiumFactoryProvider.java:8)
at com.android.webview.chromium.c.a (c.java:6)
at com.android.webview.chromium.WebViewChromium.onCheckIsTextEditor (WebViewChromium.java:17)
at android.webkit.WebView.onCheckIsTextEditor (WebView.java:3121)
at android.view.inputmethod.InputMethodManager.checkFocusNoStartInput (InputMethodManager.java:2111)
at android.view.inputmethod.InputMethodManager.checkFocus (InputMethodManager.java:2073)
at android.view.inputmethod.InputMethodManager.restartInput (InputMethodManager.java:1758)
at android.widget.TextView.setText (TextView.java:6320)
at android.widget.TextView.setText (TextView.java:6253)
at android.widget.EditText.setText (EditText.java:234)
at android.widget.TextView.setText (TextView.java:6197)
at com.facebook.react.views.textinput.ReactTextInputLocalData.apply (ReactTextInputLocalData.java:42)
at com.facebook.react.views.textinput.ReactTextInputShadowNode.measure (ReactTextInputShadowNode.java:114)
at com.facebook.yoga.YogaNodeJNIBase.measure (YogaNodeJNIBase.java:523)
at com.facebook.yoga.YogaNative.jni_YGNodeCalculateLayoutJNI (YogaNative.java)
at com.facebook.yoga.YogaNodeJNIBase.calculateLayout (YogaNodeJNIBase.java:221)
at com.facebook.react.uimanager.ReactShadowNodeImpl.calculateLayout (ReactShadowNodeImpl.java:465)
at com.facebook.react.uimanager.UIImplementation.calculateRootLayout (UIImplementation.java:950)
at com.facebook.react.uimanager.UIImplementation.updateViewHierarchy (UIImplementation.java:672)
at com.facebook.react.uimanager.UIImplementation.dispatchViewUpdates (UIImplementation.java:633)
at com.facebook.react.uimanager.UIImplementation.dispatchViewUpdatesIfNeeded (UIImplementation.java:648)
at com.facebook.react.uimanager.UIImplementation.updateNodeSize (UIImplementation.java:218)
at com.facebook.react.uimanager.UIManagerModule.updateNodeSize (UIManagerModule.java:464)
at com.swmansion.rnscreens.Screen$updateScreenSizePaper$1.runGuarded (Screen.kt:81)
at com.facebook.react.bridge.GuardedRunnable.run (GuardedRunnable.java:30)
Caused by java.util.concurrent.TimeoutException:
at java.util.concurrent.FutureTask.get (FutureTask.java:206)
at cB0.c (cB0.java:30)

<WebView
        style={styles.webview}
        androidLayerType="hardware"
        ref={webViewRef}
        originWhiteList={['*']}
        source={{
          uri: links[params.route.name],
        }}
        startInLoadingState={true}
        renderLoading={() => (
          <View style={styles.loadingContainer}>
            <ActivityIndicator size={50} color="#a9a9a9" />
          </View>
        )}
        userAgent="Mozilla/5.0 (Linux; Android;) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36 Friendchat/Android "
      />

Environment:

  • OS:android
  • OS version:Android 10 (SDK 29)
  • react-native version:^0.70.6
  • react-native-webview version:^11.23.0
@TheAlmightyBob
Copy link
Collaborator

This does not look related to react-native-webview... yes it looks like it's related to the presence of a WebView, but that stack trace doesn't reference anything from this library... rather, it seems related to the presence of a TextInput component and how that's being used? Hard to know without the full app code, but there's an investigation of another project with the same error here: zulip/zulip-mobile#4051 (comment)

@github-actions
Copy link

Hello 👋, this issue has been opened for more than 2 months with no activity on it. If the issue is still here, please keep in mind that we need community support and help to fix it! Just comment something like still searching for solutions and if you found one, please open a pull request! You have 7 days until this gets closed automatically

@Vatousiadis
Copy link

Suddenly this started happening on our app, only on Android 10 devices. I am saying suddenly because we are running webview for 2 years and this is the 1st time we see this persisting issue. Moreover it started happening out of the blue, because we have not put changes in our Webview implementation for many months now. Is there some solution to fix/bypass this crash
Any help would be appreciated because this crash is a thron in my brain for a week now

@oleksandr-dziuban
Copy link

oleksandr-dziuban commented Feb 3, 2024

Yes, this error is actual, we strated getting 10-15 crashes per week on Android 10 devices @TheAlmightyBob @Vatousiadis

Crash:

Fatal Exception: java.lang.RuntimeException
Probable deadlock detected due to WebView API being called on incorrect thread while the UI thread is blocked.

Stack:

Caused by java.util.concurrent.TimeoutException:
       at java.util.concurrent.FutureTask.get(FutureTask.java:206)
       at WV.XX.c(chromium-TrichromeWebViewGoogle6432.aab-stable-609923033:25)
       at com.android.webview.chromium.WebViewChromiumFactoryProvider.h(chromium-TrichromeWebViewGoogle6432.aab-stable-609923033:8)
       at com.android.webview.chromium.h.a(chromium-TrichromeWebViewGoogle6432.aab-stable-609923033:6)
       at com.android.webview.chromium.WebViewChromium.onCheckIsTextEditor(chromium-TrichromeWebViewGoogle6432.aab-stable-609923033:19)
       at android.webkit.WebView.onCheckIsTextEditor(WebView.java:3041)
       at android.view.inputmethod.InputMethodManager.checkFocusNoStartInput(InputMethodManager.java:1908)
       at android.view.inputmethod.InputMethodManager.checkFocus(InputMethodManager.java:1870)
       at android.view.inputmethod.InputMethodManager.restartInput(InputMethodManager.java:1586)
       at android.widget.TextView.setText(TextView.java:6191)
       at android.widget.TextView.setText(TextView.java:6124)
       at android.widget.EditText.setText(EditText.java:122)
       at android.widget.TextView.setText(TextView.java:6076)
       at com.facebook.react.views.textinput.ReactTextInputLocalData.apply(ReactTextInputLocalData.java:42)
       at com.facebook.react.views.textinput.ReactTextInputShadowNode.measure(ReactTextInputShadowNode.java:114)
       at com.facebook.yoga.YogaNodeJNIBase.measure(YogaNodeJNIBase.java:523)
       at com.facebook.yoga.YogaNative.jni_YGNodeCalculateLayoutJNI(YogaNative.java)
       at com.facebook.yoga.YogaNodeJNIBase.calculateLayout(YogaNodeJNIBase.java:221)
       at com.facebook.react.uimanager.ReactShadowNodeImpl.calculateLayout(ReactShadowNodeImpl.java:465)
       at com.facebook.react.uimanager.UIImplementation.calculateRootLayout(UIImplementation.java:950)
       at com.facebook.react.uimanager.UIImplementation.updateViewHierarchy(UIImplementation.java:672)
       at com.facebook.react.uimanager.UIImplementation.dispatchViewUpdates(UIImplementation.java:633)
       at com.facebook.react.uimanager.UIManagerModule.onBatchComplete(UIManagerModule.java:803)
       at com.facebook.react.uimanager.ReanimatedUIManager.onBatchComplete(ReanimatedUIManager.java)
       at com.facebook.react.bridge.NativeModuleRegistry.onBatchComplete(NativeModuleRegistry.java:140)
       at com.facebook.react.bridge.CatalystInstanceImpl$BridgeCallback.onBatchComplete(CatalystInstanceImpl.java:183)
       at com.facebook.jni.NativeRunnable.run(NativeRunnable.java)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
       at android.os.Looper.loop(Looper.java:224)
       at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)
       at java.lang.Thread.run(Thread.java:919)

@oleksandr-dziuban
Copy link

One of the possible solutions is to create a patch-package for react-native-webview with this tweak described here:

https://stackoverflow.com/questions/58519749/android-10-probable-deadlock-detected-due-to-webview-api-being-called-on-incor

File:
RNCWebViewManager.java

Change:

import android.os.Looper;
// ....
protected static class RNCWebView extends WebView implements LifecycleEventListener {
   // ....
   @Override
   public boolean onCheckIsTextEditor() {
       if (Looper.myLooper() == Looper.getMainLooper()) {
          return super.onCheckIsTextEditor();
       } else {
          return false;
       }
   }
}

@oleksandr-dziuban
Copy link

But seems like it doesn't work

@lean098
Copy link

lean098 commented Mar 12, 2024

But seems like it doesn't work

Yes, I implemented it in my app (https://bit.ly/Tik_Downloader), but the error persists 😕

@ihor-zhakun
Copy link

same for me, android 10 crash on webview

@abercquest
Copy link

abercquest commented Apr 18, 2024

Taking into account that ReactTextInputLocalData.apply runs in background thread and it changes the UI state it may be the cause of the issues. As in Android it is allowed to change UI state only from the main thread.

That is why the possible solution can be to add the following file:

*
 * Wrapper around OriginalReactTextInputLocalData that runs `apply` method on UI thread.
 * */
public final class ReactTextInputLocalData {

    private final OriginalReactTextInputLocalData original;

    public ReactTextInputLocalData(EditText editText) {
        Log.d("ReactTextInputLocalData", "apply");
        original = new OriginalReactTextInputLocalData(editText);
    }

    public void apply(EditText editText) {
        Log.d("ReactTextInputLocalData", "apply");
        editText.post(() -> original.apply(editText));
    }

    /*
     * Original implementation of com.facebook.react.views.textinput.ReactTextInputLocalData
     * */
    public static final class OriginalReactTextInputLocalData {
        private final SpannableStringBuilder mText;
        private final float mTextSize;
        private final int mMinLines;
        private final int mMaxLines;
        private final int mInputType;
        private final int mBreakStrategy;
        private final CharSequence mPlaceholder;

        public OriginalReactTextInputLocalData(EditText editText) {
            this.mText = new SpannableStringBuilder(editText.getText());
            this.mTextSize = editText.getTextSize();
            this.mInputType = editText.getInputType();
            this.mPlaceholder = editText.getHint();
            this.mMinLines = editText.getMinLines();
            this.mMaxLines = editText.getMaxLines();
            if (VERSION.SDK_INT >= 23) {
                this.mBreakStrategy = editText.getBreakStrategy();
            } else {
                this.mBreakStrategy = 0;
            }
        }

        public void apply(EditText editText) {
            editText.setText(this.mText);
            editText.setTextSize(0, this.mTextSize);
            editText.setMinLines(this.mMinLines);
            editText.setMaxLines(this.mMaxLines);
            editText.setInputType(this.mInputType);
            editText.setHint(this.mPlaceholder);
            if (VERSION.SDK_INT >= 23) {
                editText.setBreakStrategy(this.mBreakStrategy);
            }
        }
    }
}

It must be in the package com.facebook.react.views.textinput.
So this file replaces original ReactTextInputLocalData and runs apply method in the main thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants