Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 10: "Probable deadlock detected due to WebView API being called on incorrect thread while the UI thread is blocked"

My app consist of Fragments with fullscreen WebView. When user click on a link in the WebView then is opened new Fragment with new WebView with the same URL. Before open new Fragment I close soft keyboard just in case. I open new page very quick. All operations perform on the main thread.

By the Crashlytics the problem appers only on the Android 10 (all Pixel-series devices and other devices with 10). On devices before Android 10 all works fine. I can open much Fragments. But on Android 10 devices this case leads to FATAL EXCEPTION (after 2-3 quick attempts to open new page, randomly):

E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: <myapp>, PID: 12487
java.lang.RuntimeException: Probable deadlock detected due to WebView API being called on incorrect thread while the UI thread is blocked.
    at Yp.a(PG:13)
    at com.android.webview.chromium.WebViewChromium.onCheckIsTextEditor(PG:4)
    at android.webkit.WebView.onCheckIsTextEditor(WebView.java:3035)
    at android.view.inputmethod.InputMethodManager.checkFocusNoStartInput(InputMethodManager.java:1901)
    at android.view.inputmethod.InputMethodManager.checkFocus(InputMethodManager.java:1863)
    at android.view.inputmethod.InputMethodManager.hideSoftInputFromWindow(InputMethodManager.java:1506)
    at android.view.inputmethod.InputMethodManager.hideSoftInputFromWindow(InputMethodManager.java:1475)
    at <myapp>.Utils.hideKeyboard(Utils.java:175)
    at <myapp>.openNewPage(Pager.java:210)
    ...
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)
 Caused by: java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask.get(FutureTask.java:206)
    at Yp.a(PG:11)

I tried to use all available versions of the Android System WebView (stable, beta, dev, canary) but nothing to help.
Anybody can help me?

Update:
If I comment code for hiding soft keyboard then all works fine.

like image 583
ilyamuromets Avatar asked Oct 23 '19 09:10

ilyamuromets


3 Answers

This is not solution, only explain the issue.

First, you said "All operations perform on the main thread.", but it is wrong. The stack trees has indicated it is in a Worker thread.

And it is also can be confirmed from source code. WebView's blocking task.

Second, the code changed in Android Q, which checks view is text editor from this version.

Third, you post one task using View.post(). It is in UI thread, and the process is different in WebView (That is, it needn't wait and block)

In summary, InputMethodManager starts a task (WebView.onCheckIsTextEditor()) in non-UI thread, and WebView wants do it in UI thread, but it don't get result for timeout(4 seconds).

So it is because you have too much work in the UI thread

like image 51
bendlo Avatar answered Oct 13 '22 22:10

bendlo


I think this is not the correct way to solve this problem, but it should work around this problem by extending WebView class and overriding onCheckIsTextEditor() method:

@Override
public boolean onCheckIsTextEditor() {
    try {
        return super.onCheckIsTextEditor();
    } catch (Throwable th) {
        // Probable deadlock detected due to WebView API being called on incorrect thread while the UI thread is blocked.
        return true; // or return false in your scenario.
    }
}
like image 2
Hexise Avatar answered Oct 14 '22 00:10

Hexise


I have found a solution but not sure that it's correct. If anybody know the reason this crash or more elegant solution I'll be grateful.

Solution: wrap hideSoftInputFromWindow() in the View.post():

public static void hideKeyboard(@NotNull Context context, @NotNull View view, int flags) {
  view.post(() ->
    ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE))
      .hideSoftInputFromWindow(view.getWindowToken(), flags));
}
like image 1
ilyamuromets Avatar answered Oct 13 '22 23:10

ilyamuromets