WebView之WebViewClient详解

一、与WebChromeClient的区别
1.WebChromeClient主要辅助WebView处理JavaScript的对话框、网站图标、网站title、加载进度等比如

onProgressChanged//加载进度,可以在这里实现顶部进度条
onJsAlert //WebView上alert无效,需要定制WebChromeClient处理弹出,设置webView.setWebChromeClient(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时应用自行处理,不调用系统浏览器,并需开发者自行调用 view.loadUrl(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) {

                //LogData.i("WebView==url:", url);
                if (url == null) return false;

                try {
                    if (!url.startsWith("http://") && !url.startsWith("https://")) {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                        return true;
                    }
                } catch (Exception e) {//防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
                    return true;//没有安装该app时,返回true,表示拦截自定义链接,但不跳转,避免弹出上面的错误页面
                }


                //返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
                view.loadUrl(url);
                return true;
            }
        });

在Android N中 shouldOverrideUrlLoading(WebView view, String url)已经过时,改为shouldOverrideUrlLoading(WebView view, WebResourceRequest request),我们可以通过request.getUrl()来获取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);
    mProgressDialog.show();

 }

 @Override
public void onPageFinished(WebView view, String url) {
  super.onPageFinished(view, url);
  mProgressDialog.hide();

 }

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) {
//      一定要注释掉!    
//      super.onReceivedSslError(view, handler, error);
        handler.proceed();
}

我们这里注释掉super.onReceivedSslError(view, handler, error);是为了取消系统的默认行为(系统默认是调用handler.cancel();来取消加载),然后调用handler.proceed()来忽略错误继续加载页面。

注意:
当出现SSL错误时,WebView默认是取消加载当前页面,只有去掉onReceivedSslError的默认操作,然后添加SslErrorHandler.proceed()才能继续加载出错页面

当HTTPS传输出现SSL错误时,错误会只通过onReceivedSslError回调传过来,不会执行onReceivedError

5、shouldInterceptRequest (WebView view, String url)

该函数会在请求资源前调用,每一次请求资源时(如:超链接、图片等)都会通过这个函数来回调。需要注意的是:该函数是在非主线程进行的,所以在其中不能直接做UI操作,如需操作则可以通过handle来实现。如果不想处理直接返回null,让它继续加载资源

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值