1.旧版的onReceiveError(在API23(Build.VERSION_CODES.M)之前)
public void onReceivedError(WebView view, int errorCode,String description, String failingUrl);
文档是:
Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable). The errorCode parameter corresponds to one of the ERROR_* constants.
简单来说,onReceivedError只有在遇到不可用的(unrecoverable)错误时,才会被调用)。比如,当WebView加载链接www.baidiu.com时,”不可用”的情况有可以包括有:
-
没有网络连接
-
连接超时
-
找不到页面www.baidu.com
而下面的情况则不会报告:
-
网页内引用其他资源加载错误,比如图片、css不可用
-
js执行错误
2.新版的onReceiveError
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error);
新版的onReceiveError能接收到的错误更多,不再局限于之前的”不可用”的情况——比之前更强大了。
但是,这时候如果我们依然用使用旧版本的方式来使用新版,这会导致的问题是:在Android6.0以上的机器上,网页中的任意一个资源获取不到(比如字体),网页就很可能显示自定义的错误界面。尤其是如果Html用了本地化技术,’ERR_FILE_NOT_FOUND’开始变得特别常见。
解决方案:isForMainFrame
对isForMainFrame的描述
Gets whether the request was made for the main frame
获取当前的网络请求是否是为main frame创建的.
代码如下:
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, errorCode, description, failingUrl);
if(request.isForMainFrame()){
// 显示自定义error界面
}
}
最终代码:
// 旧版本,会在新版本中也可能被调用,所以加上一个判断,防止重复显示
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
return;
}
// 在这里显示自定义错误页
}
// 新版本,只会在Android6及以上调用
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (request.isForMainFrame()){
// 在这里显示自定义错误页
}
}
3.自定义Error页面
webview 本身就是一个viewgroup(继承viewgroup)
public class NestedScrollWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
view.clearView();// 刷新时,移除默认的 error page
view.removeAllViews(); // 刷新webview的时候,移除 自定义的error page
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (request.isForMainFrame()) {
View errorView = View.inflate(view.getContext(), mErrorPageLayoutId, null);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
view.addView(errorView, 0, layoutParams);
}
}
@SuppressWarnings("deprecation")
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
return;
}
View errorView = View.inflate(view.getContext(), mErrorPageLayoutId, null);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
view.addView(errorView, 0, layoutParams);
}
}
网友评论