一、与WebChromeClient的区别
主要辅助WebView处理JavaScript的对话框、网站图标、网站title、加载进度等比如
onProgressChanged//加载进度,可以在这里实现顶部进度条
onJsAlert //WebView上alert无效,需要定制WebChromeClient处理弹出,设置(new WebChromeClient());即可
onJsPrompt
onJsConfirm
2、WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:
shouldOverrideUrlLoading//WebView中打开新链接时调用,下面详解
onLoadResource
onPageStart
onPageFinish
onReceiveError
二、主要API
1、shouldOverrideUrlLoading(WebView view, String url)
/**
* Give the host application a chance to take over the control when a new
* url is about to be loaded in the current WebView. If WebViewClient is not
* provided, by default WebView will ask Activity Manager to choose the
* proper handler for the url. If WebViewClient is provided, return true
* means the host application handles the url, while return false means the
* current WebView handles the url.
* This method is not called for requests using the POST "method".
*
* 该方法主要是为了判断新网页的打开方式,当一个新的请求地址在页面发起时,如果没有设置WebViewClient系统默认返回false,即调用系统自带浏览器打开。
* 如果设置了WebViewClient,默认返回false,当返回true时应用自行处理,不调用系统浏览器,并需开发者自行调用 (url);
* 对于使用POST“方法”的请求,不调用此方法
*
* @param view 当前WebView
* @param url 加载的url
* @return True if the host application wants to leave the current WebView
* and handle the url itself, otherwise return false.
* @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
* shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
*/
@Deprecated
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
当我们需要当前应用自行处理,不调用系统浏览器的时候,应该重写该方法,让其返回true。**需要注意的是:**WebView只能识别”http://”和”https://”开头的协议,如果是我们自定义的协议,比如:”weixin://”将无法识别,报:ERR_UNKNOWN_URL_SCHEME 错误。所以我们可以这样来写:
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//("WebView==url:", url);
if (url == null) return false;
try {
if (!("http://") && !("https://")) {
Intent intent = new Intent(Intent.ACTION_VIEW, (url));
startActivity(intent);
return true;
}
} catch (Exception e) {//防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
return true;//没有安装该app时,返回true,表示拦截自定义链接,但不跳转,避免弹出上面的错误页面
}
//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
(url);
return true;
}
});
在Android N中 shouldOverrideUrlLoading(WebView view, String url)已经过时,改为shouldOverrideUrlLoading(WebView view, WebResourceRequest request),我们可以通过()来获取url。
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return super.shouldOverrideUrlLoading(view, request);
}
2、onPageStarted(WebView view, String url, Bitmap favicon)
该方法和onPageFinished(WebView view, String url)一起来看,和字面意思一样,onPageStarted是开始加载时调用,onPageFinished是加载完成后调用。所以我们可以用来做一些加载进度处理,比如说;开始时显示dialog,加载完毕时隐藏dialog
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
();
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
();
}
3、onReceivedError (WebView view, int errorCode,String description, String failingUrl)
加载错误的时候会回调,在其中可做错误处理,比如再请求加载一次,或者显示自定义错误页面
参数:
WebView view:当前的WebView实例
int errorCode:错误码
String description:错误描述
String failingUrl:当前出错的URL
4、onReceivedSslError (WebView view, SslErrorHandler handler,SslError error)
我们知道HTTPS协议是通过SSL来通信的,所以当使用HTTPS通信的网址(以https://开头的网站)出现错误时,就会通过onReceivedSslError回调通知过来
参数:
WebView view:当前的WebView实例
SslErrorHandler handler:当前处理错误的Handler,它只有两个函数SslErrorHandler.proceed()和SslErrorHandler.cancel(),SslErrorHandler.proceed()表示忽略错误继续加载,SslErrorHandler.cancel()表示取消加载。在onReceivedSslError的默认实现中是使用的SslErrorHandler.cancel()来取消加载,所以一旦出来SSL错误,HTTPS网站就会被取消加载了,如果想忽略错误继续加载就只有重写onReceivedSslError,并在其中调用SslErrorHandler.proceed()
SslError error:当前的的错误对象,SslError包含了当前SSL错误的基本所有信息
默认加载SSL出错的网站会出现空白页面 ,这个时候我们可以这样来做:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// 一定要注释掉!
// (view, handler, error);
();
}
我们这里注释掉(view, handler, error);是为了取消系统的默认行为(系统默认是调用();来取消加载),然后调用()来忽略错误继续加载页面。
注意:
当出现SSL错误时,WebView默认是取消加载当前页面,只有去掉onReceivedSslError的默认操作,然后添加()才能继续加载出错页面
当HTTPS传输出现SSL错误时,错误会只通过onReceivedSslError回调传过来,不会执行onReceivedError
5、shouldInterceptRequest (WebView view, String url)
该函数会在请求资源前调用,每一次请求资源时(如:超链接、图片等)都会通过这个函数来回调。需要注意的是:该函数是在非主线程进行的,所以在其中不能直接做UI操作,如需操作则可以通过handle来实现。如果不想处理直接返回null,让它继续加载资源