不幸的是,目前在 WebView 中没有简单的方法来确保页面上的所有内容都已成功加载。我们希望在未来的版本中出现更好的 API。让我解释一下你现在可以做什么。
首先,为了检测任何阻止 WebView 连接到服务器以加载您的主页的问题(例如,错误的域名、I/O 错误等),您应该使用WebViewClient.onReceivedError 回调正如其他人正确建议的那样:
public class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Make a note about the failed load.
}
}
myWebView.setWebViewClient(new MyWebViewClient());
如果服务器连接成功,并且主页面被检索和解析,你会收到WebView.onPageFinished回调,所以你还需要在你的WebViewClient子类中有这个:
public class MyWebViewClient extends WebViewClient {
...
@Override
public void onPageFinished(WebView view, String url) {
// Make a note that the page has finished loading.
}
...
}
这里需要注意的是,如果您从服务器收到 HTTP 错误(例如 404 或 500 错误),无论如何都会调用此回调,它只是您将在 WebView 中获得的内容将是服务器错误页面。人们提出了不同的处理方法,请在此处查看答案:How can I check from Android WebView if a page is a "404 page not found"? 基本上,这实际上取决于您期望成为“好”页面和“错误”页面的内容。遗憾的是,应用目前无法从 WebView 获取 HTTP 响应代码。
回调WebViewClient.onPageStarted 和WebViewClient.onProgressChanged 仅在您想在加载页面时绘制进度条时才有用。
还要注意,人们通常建议的覆盖WebViewClient.shouldOverrideUrlLoading 的方式是不正确的:
public class MyWebViewClient extends WebViewClient {
...
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// !!! DO NOT DO THIS UNCONDITIONALLY !!!
view.loadUrl(url);
return true;
}
...
}
很少有开发人员意识到,对于非 https 方案的子帧也会调用回调。如果您遇到类似<iframe src='tel:1234'> 的内容,您最终将执行view.loadUrl('tel:1234'),并且您的应用程序将显示错误页面,因为WebView 不知道如何加载tel: URL。
如果您希望 WebView 进行加载,建议简单地从方法中返回 false:
public class MyWebViewClient extends WebViewClient {
...
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Returning 'false' unconditionally is fine.
return false;
}
...
}
这并不意味着您根本不应该从shouldOverrideUrlLoading 调用WebView.loadUrl。要避免的特定模式是对所有 URL 无条件地这样做。