一个例子让我理解WebViewClient各方法重写的作用

 

 

摘要:

创建并设置一个WebViewClient子类,回调对应的方法改变网页内容的呈现方式,比如:网页加载错误回调onReceivedError(),提交表单错误回调onFormResubmission(),拦截URL加载回调shouldOverrideUrlLoading()方法,判断是否加载同一条url回调onPageStarted(),处理一个HTTP认证请求回调onReceivedHttpAuthRequest()方法,获取请求的数据回调shouldInterceptRequest()方法,拦截事件处理回调shouldOverrideKeyEvent()方法等等

其他方法的作用,如下:

  1. doUpdateVisitedHistory(WebView view, String url, boolean isReload)  

更新浏览历史记录,获取更新的url地址

  1. onLoadResource(WebView view, String url)  

加载给定url资源内容

  1. onPageCommitVisible(WebView view, String url)  

正在加载HTTP响应的body内容,回调该方法,获取对应url地址

  1. onPageFinished(WebView view, String url)  

页面加载完成回调方法,获取对应url地址

  1. onReceivedClientCertRequest(WebView view, ClientCertRequest request)  

回调该方法,处理SSL认证请求

  1. onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)  

回调该方法,处理HTTP认证错误

  1. onReceivedLoginRequest(WebView view, String realm, String account, String args)  

回调该方法,请求已授权用户自动登录

  1. onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)  

回调该方法,处理SSL认证错误

  1. onScaleChanged(WebView view, float oldScale, float newScale)  

页面大小改变后回调该方法,获取缩放前后大小

  1. onUnhandledKeyEvent(WebView view, KeyEvent event)  

回调该方法,处理未被WebView处理的事件

  1. shouldOverrideKeyEvent(WebView view, KeyEvent event)  

给予主机应用程序异步处理按键事件的机会

一个例子带我理解各个方法的作用

查看文档不难读懂重写每个方法的目的,尽管理解大概的意思,但缺少例子的演示,总感觉又不是很理解WebViewClient各个方法重写的作用,TeachCourse这就带你从例子角度理解它们的作用,深入理解WebViewClient在改变网页渲染方式上,应该回调哪个方法。

1、onReceivedError(),网络不好或服务器请求超时,WebView加载指定页面,请求不到数据,加载出错,WebView默认错误处理效果如下图
一个例子让我理解WebViewClient各方法重写的作用

回调onReceivedError(),自己定义加载错误处理效果,比如:TeachCourse定义在没有网络时候,显示一张无网络的图片,如下图
一个例子让我理解WebViewClient各方法重写的作用

API 23之前回调onReceivedError(WebView view, int errorCode, String description, String failingUrl);API 23之后回调onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)方法,在开发的应用程序中,最好同时重写上面两个错误处理的方法,兼容不同API版本,防止设置无效。

2、onFormResubmission(),由于页面需要使用POST方式获取结果,如果浏览器需要重发,回调onFormResubmission()方法,默认浏览器不重发请求数据。

3、shouldOverrideUrlLoading(),WebView加载H5界面,点击按钮发送短信或拨打电话,调不起短信编辑界面或拨打电话界面,通常都是因为没有重写shouldOverrideUrlLoading,拦截发送短信或拨打电话的url,处理H5界面请求。

H5页面使用a标签的href属性添加发送短信超链接:

  1. <a href="sms:182xxxxxx">一键短信发送</a>  

处理发送短信请求,重写shouldOverrideUrlLoading,如下:

  1. /** 
  2.  *定义处理正在加载url的方式 
  3.  * @author 钊林IT 
  4.  * @param view 
  5.  * @param url 
  6.  * @return 当前浏览器处理正在加载的url,默认返回false;否则返回true 
  7.  */  
  8. public boolean shouldOverrideUrlLoading(WebView view, String url) {  
  9.         if (url.startsWith("http:") || url.startsWith("https:")) {  
  10.                 return false;  
  11.         }  
  12.         /** 
  13.          * 处理特殊的url地址,比如“sms:” 
  14.          */  
  15.         if (url.startsWith("sms:")) {  
  16.         Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));     
  17.         view.getContext().startActivity(intent);   
  18.         }  
  19.      return true;  
  20. }  

同理,处理拨打H5界面电话请求

  1. <a href="tel:182xxxxxx">一键拨打电话</a>  
  1. /** 
  2.  * 处理特殊的url地址,比如“tel:” 
  3.  * @author 钊林IT 
  4.  */  
  5. if (url.startsWith("tel:")) {  
  6.      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));  
  7.      view.getContext().startActivity(intent);  
  8.     return true;  
  9. }  

实现H5界面和原生APP交互,还可以使用JavaScript脚本,点击H5页面按钮时,通过脚本传递的对象,调用APP提供的方法,比如:发送短信或拨打电话。API 24以后改用 shouldOverrideUrlLoading(WebView, WebResourceRequest) 代替shouldOverrideUrlLoading (WebView view, String url),为了兼容不同API版本,最好同时重写上述两种方法。

4、onPageStarted(),在一个Activity首页展示一个H5弹窗,点击其中一条超链接,使用指定的浏览器打开,重写onPageStarted()监听即将加载的url是否需要使用指定的浏览器打开,onPageStarted为当前弹窗设置WebViewClient重写的一个方法,代码如下:

  1. @Override  
  2. public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  3.       super.onPageStarted(view, url, favicon);  
  4.          if (mUrl.equals(url)||TextUtils.isEmpty(url)) {  
  5.                return;  
  6.          }  
  7.       Intent intent = new Intent(PopupWindowActivity.this, BaseWebActivity.class);  
  8.          intent.putExtra("url",url);  
  9.          startActivity(intent);  
  10. }  

5、onReceivedHttpAuthRequest(),当前应用程序的WebView接收一个HTTP认证请求,使用提供的HttpAuthHandler对象设置WebView对HTTP认证请求的响应,默认WebView取消HTTP认证,即handler.cancel()

6、shouldInterceptRequest(),请求资源的主机应用程序允许应用程序返回数据,如果该方法返回null,WebView将会按照平常一样继续加载;否则,返回的内容将会被使用。该方法在独立线程而非UI线程中回调,因此访问私有数据或系统视图时应该谨慎行事。

7、doUpdateVisitedHistory(),当前WebView加载的url被重新加载,isReload为true,这一步可以判读是否执行刷新操作,如下:

  1. @Override  
  2. public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {  
  3.         super.doUpdateVisitedHistory(view, url, isReload);  
  4.            if (isReload)  
  5.         Toast.makeText(activity,"刷新成功",Toast.LENGTH_SHORT).show();  
  6. }  

8、onLoadResource (),加载指定url资源,判读是否为.apk文件,然后启动系统的文件下载管理器,下载指定的文件,如下:

  1. @Override  
  2. public void onLoadResource(WebView view, String url) {  
  3.        super.onLoadResource(view, url);  
  4.           if (url.endsWith(".apk"))  
  5.              loadManager(url);  
  6. }  

9、onPageCommitVisible(),页面加载完成可见,如下:

  1. @Override   
  2. public void onPageCommitVisible(WebView view, String url) {  
  3.       super.onPageCommitVisible(view, url);  
  4.       mProgressBar.setVisibility(ProgressBar.GONE);  
  5.       webView.setVisibility(View.VISIBLE);  
  6.       isWebViewLoadingFirstPage=false;  
  7. }  

10、onPageFinished(),页面加载结束,回调该方法,如下:

  1. @Override  
  2. public void onPageFinished(WebView view, String url) {  
  3.        super.onPageFinished(view, url);  
  4.          Toast.makeText(activity,"页面加载结束",Toast.LENGTH_SHORT).show();  
  5. }  

11、onReceivedClientCertRequest(),提醒主机应用程序处理SSL客户端认证请求,如果客户端提供的keys符合,主机应用程序响应客户端请求并展示UI界面。主机应用程序有三种方法响应:第一种,proceed();第二种,cancel();第三种,ignore();如果调用proceed()或cancel(),WebView在内存保留请求的结果,同时同一请求不会再次回调onReceivedClientCertRequest()方法。如果调用ignore()方法,WebView不保存请求结果。

由于网络堆栈的多层级缓存请求结果,因此ignore()响应方式是唯一最好的选择。onReceivedClientCertRequest()方法在UI线程中调用,在回调该方法时,请求网络连接是暂停的。

12、onReceivedHttpError(),提醒主机应用程序,正在加载数据资源的时候,接收到一个来自服务器的HTTP认证错误,HTTP错误认证码>=400,除了加载网页内容,该方法都会被调用。因此,在该回调方法中最好执行最少的请求操作,同时服务器响应的结果内容不会在errorResponse参数中返回。

13、onReceivedLoginRequest(),提醒主机应用程序,请求已授权用户自动登录

14、onReceivedSslError(),提醒主机应用程序,正在加载数据资源的时候,出现了SSL认证错误,这个时候的主机应用程序必须调用handler.cancel()或handler.proceed()方法中的一个,默认调用cancel()方法。

15、onScaleChanged(),提醒主机应用程序,被应用于WebView的比例发生了改变

  1. @Override  
  2. public void onScaleChanged(WebView view, float oldScale, float newScale) {  
  3.         super.onScaleChanged(view, oldScale, newScale);  
  4.         float size=oldScale/newScale;  
  5.         Toast.makeText(view.getContext(),"WebView比例改变:"+size,Toast.LENGTH_SHORT).show();  
  6. }  

16、onUnhandledKeyEvent(),提醒主机应用程序,除了系统按键外,WebView不处理其他按键操作。通常流程,WebView总是消耗所有按键操作。按键被处理的时候异步回调该方法,给予主机应用程序一个处理未处理按键事件的机会。

17、shouldOverrideKeyEvent(),给予主机应用程序一个异步处理按键事件的机会,菜单快捷键在该方法中被拦截。WebView将不处理按键事件,返回true;否则默认返回false,WebView总是处理所有的按键事件。如果没有使用super关键字回调父类的shouldOverrideKeyEvent()方法,该方法将接收所有按键事件。

  1. @Override  
  2. public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {  
  3.         return true;  
  4. }  

相关阅读

详细了解WebChromeClient源码各方法使用说明

Android开发深入理解WebChromeClient之onShowFileChooser或openFileChooser使用说明

WebView控件之WebSettings各种配置方法源码总结

上一篇:关于安卓中的 shouldOverrideUrlLoading 方法的问题


下一篇:小程序webview涉及的支付能力、选用绑定多商户支付