Android 4.4 KitKat上的shouldInterceptRequest

5
我有一个应用程序,在Android WebViewClient的shouldInterceptRequest(WebView view,String url)shouldOverrideUrlLoading(WebView view,String url)中使用自定义方案来拦截Web应用程序中的请求,并在shouldInterceptRequest中使用本地库从其他地方获取资源。这一直运作良好,直到Android 4.4 KitKat,Google对webView组件进行了一些关键更改。

http://developer.android.com/guide/webapps/migrating.html#URLs

现在在shouldOverrideUrlLoading中接收到的URL突然变成无效的,看起来像这样:custom-scheme:////my.pathname.com/。起初我怀疑额外的斜杠是因为Android认为URL不符合RFC3986标准,但在一系列资源获取(CSS、JS、图像)中,URL一开始是正确的,然后突然变成无效格式。 Android 4.3中的webView将URL正确保留为custom-scheme://my.pathname.com/。似乎基本URL突然更改为“/'而不是'my.pathname.com'。

然后我的注意力转向webView 4.4迁移指南所提到的:

如果您从任何线程调用WebView上的方法而不是您的应用程序的UI线程,则可能会导致意外结果。 http://developer.android.com/guide/webapps/migrating.html#Threads

这也可能是我正在经历的问题,但我还没有想出一个解决方案,在其中我可以使用runOnUiThread()使用本机API获取数据并将其返回到shouldInterceptRequest内部的webView。有人遇到过类似的问题吗?

这是我shouldInterceptRequest代码的简化版本:
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        if (urlStartsWithKnownPrefix(url)) {
            UrlFetchResult fetchRes = api.fetchUrl(url);
            String charset = "utf-8";
            String mime = fetchRes.getMimetype();
            WebResourceResponse res = new WebResourceResponse(mime, charset, new ByteArrayInputStream(fetchRes.getResult()));
            return res;
        }
        return null;
    }

你在HTML中如何引用内容?你收到的URL的预期值和实际值是什么? - ksasq
当我调用webView的loadUrl(url)加载主页时,自定义方案设置在url中,我不在代码中设置基本url。我看到loadDataWithBaseURL()需要一个baseUrl参数,但是该方法用于数据而不是url。对于Android 4.4 WebView在自定义方案上工作,我必须显式设置baseUrl吗?在同一webView中使用http://一切正常,因此Android验证自定义方案与http://不同。 - MartinR
此外,如果我覆盖了 onPageStarted(WebView view, String url, Bitmap favicon)onPageFinished(WebView view, String url) 方法,我发现它开始的 URL 是 "custom-scheme://my.pathname.com/",结束的 URL 是 "custom-scheme:////my.pathname.com/"。这是一个 bug 吗? - MartinR
只是确认一下,你在你的Android清单文件中将targetSDKVersion设置为19了吗? - Matt Gaunt
你能否创建一个简化的示例并将其放在Github上,以便我可以查看和尝试一下?/ 提醒一些人看看可能出了什么问题。 - Matt Gaunt
显示剩余4条评论
1个回答

2

你说得完全正确。我最终创建了一个类似于这个pull请求的jQuery Mobile补丁:https://github.com/jquery/jquery-mobile/pull/6811/files 。同时在Android shouldInterceptRequest方法中还包括了一些额外斜线检查。这绝对不是一个漂亮的解决方案,但它是目前唯一有效的解决方案。 - MartinR
如果有自定义协议,例如_customProtocol://,该如何解决? - LOG_TAG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接