android - 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(稳定版、测试版、开发版、金丝雀版),但没有任何帮助。
任何人都可以帮助我吗?
更新:
如果我评论隐藏软键盘的代码,那么一切正常。
解决方案
这不是解决方案,只是解释问题。
首先,您说“所有操作都在主线程上执行。”,但这是错误的。堆栈树表明它在工作线程中。
也可以从源代码中确认。 WebView 的阻塞任务。
其次,Android Q 中的代码发生了变化,它检查视图是这个版本的文本编辑器。
第三,您使用 View.post() 发布一项任务。在UI线程中,与WebView中的进程不同(即不需要等待和阻塞)
综上所述,InputMethodManager 在非 UI 线程中启动了一个任务(WebView.onCheckIsTextEditor()),WebView 想在 UI 线程中执行,但超时(4 秒)没有得到结果。
所以这是因为你在 UI 线程中有太多的工作
推荐阅读
- c# - 替代 StreamReader.ReadLine(filepath) 以避免内存不足?
- ios - Flutter iOS 存档版本在 Xcode 中获取“xx plugin.h”文件未找到错误
- c - 简单 C 计算器中的分段错误
- c++ - 使用三元运算符并删除移动/复制 ctor 时,Visual Studio 不执行 RVO
- javascript - 谷歌地图中标记的打开和关闭切换按钮反应
- php - 如何在爬取中使用 dom xpath?
- python - 如何使用 pysftp/paramiko 在 python 中启用键盘交互式身份验证?
- playframework - 如何从文件系统提供静态资产而不是默认资产 JAR 包(Play 框架)
- python - 无法在 Mac OS Mojave 上导入海龟(版本 10.14.2)
- javascript - 从另一个页面上的 HTML 表单访问值