摘要:
创建并设置一个WebViewClient子类,回调对应的方法改变网页内容的呈现方式,比如:网页加载错误回调onReceivedError(),提交表单错误回调onFormResubmission(),拦截URL加载回调shouldOverrideUrlLoading()方法,判断是否加载同一条url回调onPageStarted(),处理一个HTTP认证请求回调onReceivedHttpAuthRequest()方法,获取请求的数据回调shouldInterceptRequest()方法,拦截事件处理回调shouldOverrideKeyEvent()方法等等
其他方法的作用,如下:
- doUpdateVisitedHistory(WebView view, String url, boolean isReload)
更新浏览历史记录,获取更新的url地址
- onLoadResource(WebView view, String url)
加载给定url资源内容
- onPageCommitVisible(WebView view, String url)
正在加载HTTP响应的body内容,回调该方法,获取对应url地址
- onPageFinished(WebView view, String url)
页面加载完成回调方法,获取对应url地址
- onReceivedClientCertRequest(WebView view, ClientCertRequest request)
回调该方法,处理SSL认证请求
- onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)
回调该方法,处理HTTP认证错误
- onReceivedLoginRequest(WebView view, String realm, String account, String args)
回调该方法,请求已授权用户自动登录
- onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)
回调该方法,处理SSL认证错误
- onScaleChanged(WebView view, float oldScale, float newScale)
页面大小改变后回调该方法,获取缩放前后大小
- onUnhandledKeyEvent(WebView view, KeyEvent event)
回调该方法,处理未被WebView处理的事件
- shouldOverrideKeyEvent(WebView view, KeyEvent event)
给予主机应用程序异步处理按键事件的机会
一个例子带我理解各个方法的作用
查看文档不难读懂重写每个方法的目的,尽管理解大概的意思,但缺少例子的演示,总感觉又不是很理解WebViewClient各个方法重写的作用,TeachCourse这就带你从例子角度理解它们的作用,深入理解WebViewClient在改变网页渲染方式上,应该回调哪个方法。
1、onReceivedError(),网络不好或服务器请求超时,WebView加载指定页面,请求不到数据,加载出错,WebView默认错误处理效果如下图
回调onReceivedError(),自己定义加载错误处理效果,比如:TeachCourse定义在没有网络时候,显示一张无网络的图片,如下图
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属性添加发送短信超链接:
- <a href="sms:182xxxxxx">一键短信发送</a>
处理发送短信请求,重写shouldOverrideUrlLoading,如下:
- /**
- *定义处理正在加载url的方式
- * @author 钊林IT
- * @param view
- * @param url
- * @return 当前浏览器处理正在加载的url,默认返回false;否则返回true
- */
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- if (url.startsWith("http:") || url.startsWith("https:")) {
- return false;
- }
- /**
- * 处理特殊的url地址,比如“sms:”
- */
- if (url.startsWith("sms:")) {
- Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));
- view.getContext().startActivity(intent);
- }
- return true;
- }
同理,处理拨打H5界面电话请求
- <a href="tel:182xxxxxx">一键拨打电话</a>
- /**
- * 处理特殊的url地址,比如“tel:”
- * @author 钊林IT
- */
- if (url.startsWith("tel:")) {
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- view.getContext().startActivity(intent);
- return true;
- }
实现H5界面和原生APP交互,还可以使用JavaScript脚本,点击H5页面按钮时,通过脚本传递的对象,调用APP提供的方法,比如:发送短信或拨打电话。API 24以后改用 shouldOverrideUrlLoading(WebView, WebResourceRequest) 代替shouldOverrideUrlLoading (WebView view, String url),为了兼容不同API版本,最好同时重写上述两种方法。
4、onPageStarted(),在一个Activity首页展示一个H5弹窗,点击其中一条超链接,使用指定的浏览器打开,重写onPageStarted()监听即将加载的url是否需要使用指定的浏览器打开,onPageStarted为当前弹窗设置WebViewClient重写的一个方法,代码如下:
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- if (mUrl.equals(url)||TextUtils.isEmpty(url)) {
- return;
- }
- Intent intent = new Intent(PopupWindowActivity.this, BaseWebActivity.class);
- intent.putExtra("url",url);
- startActivity(intent);
- }
5、onReceivedHttpAuthRequest(),当前应用程序的WebView接收一个HTTP认证请求,使用提供的HttpAuthHandler对象设置WebView对HTTP认证请求的响应,默认WebView取消HTTP认证,即handler.cancel()
6、shouldInterceptRequest(),请求资源的主机应用程序允许应用程序返回数据,如果该方法返回null,WebView将会按照平常一样继续加载;否则,返回的内容将会被使用。该方法在独立线程而非UI线程中回调,因此访问私有数据或系统视图时应该谨慎行事。
7、doUpdateVisitedHistory(),当前WebView加载的url被重新加载,isReload为true,这一步可以判读是否执行刷新操作,如下:
- @Override
- public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
- super.doUpdateVisitedHistory(view, url, isReload);
- if (isReload)
- Toast.makeText(activity,"刷新成功",Toast.LENGTH_SHORT).show();
- }
8、onLoadResource (),加载指定url资源,判读是否为.apk文件,然后启动系统的文件下载管理器,下载指定的文件,如下:
- @Override
- public void onLoadResource(WebView view, String url) {
- super.onLoadResource(view, url);
- if (url.endsWith(".apk"))
- loadManager(url);
- }
9、onPageCommitVisible(),页面加载完成可见,如下:
- @Override
- public void onPageCommitVisible(WebView view, String url) {
- super.onPageCommitVisible(view, url);
- mProgressBar.setVisibility(ProgressBar.GONE);
- webView.setVisibility(View.VISIBLE);
- isWebViewLoadingFirstPage=false;
- }
10、onPageFinished(),页面加载结束,回调该方法,如下:
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- Toast.makeText(activity,"页面加载结束",Toast.LENGTH_SHORT).show();
- }
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的比例发生了改变
- @Override
- public void onScaleChanged(WebView view, float oldScale, float newScale) {
- super.onScaleChanged(view, oldScale, newScale);
- float size=oldScale/newScale;
- Toast.makeText(view.getContext(),"WebView比例改变:"+size,Toast.LENGTH_SHORT).show();
- }
16、onUnhandledKeyEvent(),提醒主机应用程序,除了系统按键外,WebView不处理其他按键操作。通常流程,WebView总是消耗所有按键操作。按键被处理的时候异步回调该方法,给予主机应用程序一个处理未处理按键事件的机会。
17、shouldOverrideKeyEvent(),给予主机应用程序一个异步处理按键事件的机会,菜单快捷键在该方法中被拦截。WebView将不处理按键事件,返回true;否则默认返回false,WebView总是处理所有的按键事件。如果没有使用super关键字回调父类的shouldOverrideKeyEvent()方法,该方法将接收所有按键事件。
- @Override
- public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
- return true;
- }
相关阅读
《详细了解WebChromeClient源码各方法使用说明》
《Android开发深入理解WebChromeClient之onShowFileChooser或openFileChooser使用说明》
《WebView控件之WebSettings各种配置方法源码总结》