Android WebView 因 shouldInterceptRequest 覆盖而立即崩溃

Fli*_*int 6 android webview chromium intercept

我正在享受 Android WebView 的一些“乐趣”。

我使用它来显示登录屏幕,然后拦截响应中的身份验证代码。应该很简单...

如果我只重写 shouldOverrideUrlLoading 但如果我重写(就像 Android Studio 自动完成一样),我的 WebView 加载和显示绝对正常:

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse {
    return super.shouldInterceptRequest(view, request)
}
Run Code Online (Sandbox Code Playgroud)

如果没有其他更改,它会在运行时立即崩溃并发生本机崩溃

A/铬:[致命:jni_android.cc(259)]

其次是

A/libc:致命信号 6 (SIGABRT),tid 16220 (TaskSchedulerFo) 中的代码 -6 (SI_TKILL),pid 16175 (eports.internal)

奇怪的是,如果我将响应设为可为空,WebView 就会再次工作。但是,在 shouldInterceptRequest 方法中添加其他任何内容都会使其失败并出现相同的错误。

所以这有效:

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse? {
    return super.shouldInterceptRequest(view, request)
}
Run Code Online (Sandbox Code Playgroud)

但这会因上述崩溃而崩溃:

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse? {
    val url = view?.url
    return super.shouldInterceptRequest(view, request)
}
Run Code Online (Sandbox Code Playgroud)

这似乎是一个非常奇怪的问题,并且对我来说毫无意义为什么添加 val 赋值会产生任何影响。

我一直在研究错误并建议添加

webView.destroy()

在活动/片段 onDestroy/onDestroyView 中,不幸的是,这没有帮助。

设备和模拟器以及 Android sdk 22 和 28 上的行为相同。

以前有人见过这样的事情吗?我觉得我可能错过了一些明显的东西。

如果它对任何人有用,我也生成了 Breakpad Microdump,它太大了,无法在这个问题中发布。但请告诉我它或它的一部分是否可以帮助诊断!

Fli*_*int 6

我在我的案例中发现了这个问题,所以我想我会将其发布在这里,供其他处于类似位置的人使用。

本机崩溃是由 WebView 中运行的 Javascript 引起的。

WebView 在后台线程中运行 JavaScript,因此任何接触 UI 线程的操作都会导致它在本机级别崩溃。给出上面非常无益的崩溃。

val 分配导致崩溃的原因不是 val 的分配,而是 UIThread 上的 if view?.url 调用。

解决方案?

科特林:

webView?.post{
   // Do your UI work here.
}
Run Code Online (Sandbox Code Playgroud)

爪哇:

webView.post(new Runnable(){
    public void run() {
    // Do your UI work here.
    }
})
Run Code Online (Sandbox Code Playgroud)

并且不要在重写的方法中触摸 UIThread!