带有 shouldInterceptRequest 覆盖的 Android WebView 即时崩溃

Posted

技术标签:

【中文标题】带有 shouldInterceptRequest 覆盖的 Android WebView 即时崩溃【英文标题】:Android WebView instant crash with shouldInterceptRequest override 【发布时间】:2018-12-23 18:55:45 【问题描述】:

我正在使用 android WebView 获得一些“乐趣”。

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

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

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse 
    return super.shouldInterceptRequest(view, request)

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

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)

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

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse? 
    val url = view?.url
    return super.shouldInterceptRequest(view, request)

这似乎是一个非常奇怪的问题,对我来说为什么添加一个 val 分配会产生任何影响是没有意义的。

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

webView.destroy()

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

Device 和 Emulator 以及 Android sdk 22 和 28 上的行为相同。

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

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

【问题讨论】:

这也发生在我身上。 希望我能说我知道发生了什么。就我而言,我只是在记录 url。如果我尝试记录 url 【参考方案1】:

我在我的案例中发现了这个问题,所以我想我会把它贴在这里给其他处于类似位置的人。

Native 崩溃是由在 WebView 中运行的 javascript 引起的。

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

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

解决方案?

科特林:

webView?.post
   // Do your UI work here.

Java:

webView.post(new Runnable()
    public void run() 
    // Do your UI work here.
    
)

并且不要在被覆盖的方法中触摸 UIThread!

【讨论】:

我只是重写了 shouldInterceptRequest 方法,什么也没做,它的抛出错误没有任何错误日志【参考方案2】:

如果您正在编写 Kotlin 代码来实现 WebViewClient,则应查看此答案并检查您的 Kotlin 覆盖方法签名。

我遇到了同样的运行时异常,并发现导致此问题的原因是 Kotlin 编译器未将 Java 方法的返回类型互操作为 Kotlin 方法的返回类型。

Java代码的方法签名:

    public WebResourceResponse shouldInterceptRequest(WebView view, String url)

通过覆盖方法自动完成与 Kotlin 互操作:

    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse

缺少 Kotlin 方法返回类型 ?。 你要做的就是将?添加到WebResourceResponse,例如,

    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse?

【讨论】:

以上是关于带有 shouldInterceptRequest 覆盖的 Android WebView 即时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Webview shouldInterceptRequest方法始终返回null

使用非弃用时,应为弃用和非弃用变体调用两次 shouldInterceptRequest

WebView 不呈现 HTML/gzip 内容,该内容通过 shouldInterceptRequest() webViewClient 方法中的 HttpURLConnection 接收

Android WebView:拦截重定向请求?

Android WebView 缓存

Android 在 webview 中屏蔽广告