首页 > 解决方案 > Android 10:“由于在 UI 线程被阻止时在不正确的线程上调用 WebView API 而检测到可能的死锁”

问题描述

我的应用由带有全屏WebView的Fragments组成。当用户单击WebView中的链接时,会打开带有相同URL的新WebView的新Fragment。在打开新片段之前,我关闭软键盘以防万一。我打开新页面很快。所有操作都在主线程上执行。

通过 Crashlytics,该问题仅出现在 Android 10(所有 Pixel 系列设备和其他配备 10 的设备)上。在 Android 10 之前的设备上一切正常。我可以打开很多Fragments。但在 Android 10 设备上,这种情况会导致 FATAL EXCEPTION(在 2-3 次快速尝试随机打开新页面后):

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)

我尝试使用所有可用版本的Android 系统 WebView(稳定版、测试版、开发版、金丝雀版),但没有任何帮助。
任何人都可以帮助我吗?

更新
如果我评论隐藏软键盘的代码,那么一切正常。

标签: androidandroid-webviewandroid-softkeyboard

解决方案


这不是解决方案,只是解释问题。

首先,您说“所有操作都在主线程上执行。”,但这是错误的。堆栈树表明它在工作线程中。

也可以从源代码中确认。 WebView 的阻塞任务

其次,Android Q 中的代码发生了变化,它检查视图是这个版本的文本编辑器。

第三,您使用 View.post() 发布一项任务。在UI线程中,与WebView中的进程不同(即不需要等待和阻塞)

综上所述,InputMethodManager 在非 UI 线程中启动了一个任务(WebView.onCheckIsTextEditor()),WebView 想在 UI 线程中执行,但超时(4 秒)没有得到结果。

所以这是因为你在 UI 线程中有太多的工作


推荐阅读