新的 WebView 在请求资源和解析使用自定义 URL 方案的链接时应用了额外的限制。例如,如果您实现了诸如 shouldOverrideUrlLoading() 或 shouldInterceptRequest() 之类的回调,则 WebView 仅针对有效 URL 调用它们。
如果您使用自定义 URL 方案或基本 URL,并注意到您的应用收到的对这些回调的调用较少或无法在 Android 4.4 上加载资源,请确保请求指定符合 RFC 3986 的有效 URL。
例如,新的 WebView 可能不会为如下链接调用您的 shouldOverrideUrlLoading() 方法:
显示配置文件 用户单击此类链接的结果可能会有所不同:
如果您通过调用 loadData() 或 loadDataWithBaseURL() 并使用无效或空的基本 URL 加载页面,那么您将不会收到页面上此类链接的 shouldOverrideUrlLoading() 回调。注意:当您使用 loadDataWithBaseURL() 并且基本 URL 无效或设置为 null 时,您正在加载的内容中的所有链接都必须是绝对链接。
如果您通过调用 loadUrl() 加载页面或使用 loadDataWithBaseURL() 提供了有效的基本 URL,那么您将收到页面上此类链接的 shouldOverrideUrlLoading() 回调,但您收到的 URL 将是绝对的,相对于当前页面。例如,您收到的 URL 将是“ http://www.example.com/showProfile ”,而不仅仅是“showProfile”。除了在链接中使用简单的字符串,如上所示,您可以使用自定义方案,如下所示:
<a href="example-app:showProfile">Show Profile</a>
然后,您可以在 shouldOverrideUrlLoading() 方法中处理此 URL,如下所示:
// The URL scheme should be non-hierarchical (no trailing slashes)
private static final String APP_SCHEME = "example-app:";
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(APP_SCHEME)) {
urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8");
respondToData(urlData);
return true;
}
return false;
}
如果您无法更改 HTML,那么您可以使用 loadDataWithBaseURL() 并设置由自定义方案和有效主机组成的基本 URL,例如“example-app:///”。例如:
webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA,
null, "UTF-8", null);
有效的主机名应符合 RFC 3986 并且在末尾包含尾部斜杠很重要,否则,来自加载页面的任何请求都可能被丢弃。