Android 的 WebViewClient.shouldInterceptRequest() 仅在第一次调用

Android's WebViewClient.shouldInterceptRequest() is called only for the first time

我在 Android 应用程序中使用 WebView。 WebViewClient 用于拦截目标 "https://" REST 请求,以便我可以在本机客户端进行一些自定义处理。

问题是 WebViewClient.shouldInterceptRequest(WebView, WebResourceRequest) 仅在应用 运行 时第一次被调用。对同一 REST 服务的后续网络请求不再调用 shouldInterceptRequest()。我必须卸载应用程序或在应用程序信息系统设置中 "Clear Storage" 才能再次调用 shouldInterceptRequest()。

为了排除网站缓存服务响应的可能性,我使用Charles Proxy来监控网络流量。我可以看到每次加载网页时都会发出一个新的网络请求,无论是否触发了 shouldInterceptRequest()。

第一次shouldInterceptRequest()没有调用的原因是什么?

事实证明,我尝试嵌入的网络应用程序使用了浏览器 Service Worker。 Service Worker 发出的网络请求不能被 WebViewClient 拦截。为了拦截 Service Worker 网络请求,必须使用 ServiceWorkerClientCompat。

我的解决方案是同时设置一个 WebServiceClient 和一个 ServiceWorkerClient,因为 Service Worker 有自己的生命周期并且在某些情况下可能不会被激活(例如第一次应用程序是 运行)。

示例代码如下

if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) {
   ServiceWorkerControllerCompat.getInstance().setServiceWorkerClient(
          object : ServiceWorkerClientCompat() {
              override fun shouldInterceptRequest(request: WebResourceRequest): WebResourceResponse? {
                  // custom handling
              }
   })
}

要从 webview 捕获所有网络请求,您还需要考虑 Service Worker。 Service Worker 调用可以被拦截,但需要在 上进行设置才能做到这一点。