概览:

   Android WebView 做为承载网页的载体控件,他在网页显示的过程中会产生一些事件,并回调给我们的应用程序,以便我们在网页载入过程中做应用程序想处理的事情。比方说client须要显示网页载入的进度、网页载入错误发生等等事件。

WebView提供两个事件回调类给应用层,分别为WebViewClient,WebChromeClient开发人员能够继承这两个类,接手相应事件处理。

WebViewClient 主要提供网页载入各个阶段的通知,比方网页開始载入onPageStarted。网页结束载入onPageFinished等;WebChromeClient主要提供网页载入过程中提供的数据内容,比方返回网页的title,favicon等。

1.WebViewClient的基本使用


 创建WebViewClient实例并设置到WebView对象中,详细代码參考例如以下:



class MyAndroidWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO
}

@Override
public void onPageFinished(WebView view, String url) {
// TODO
}
}
webview.setWebViewClient(new MyAndroidWebViewClient ());


2.WebViewClient API详细解释


1)网页载入时机部分


     

public boolean shouldOverrideUrlLoading(WebView view, String url)

当载入的网页须要重定向的时候就会回调这个函数告知我们应用程序是否须要接管控制网页载入。假设应用程序接管,而且return true意味着主程序接管网页载入,假设返回false让webview自己处理。



參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。


@param url    即将要被载入的url


@return  true 当前应用程序要自己处理这个url, 返回false则不处理。




Tips


(1) 当请求的方式是"POST"方式时这个回调是不会通知的。


(2) 当我们訪问的地址须要我们应用程序自己处理的时候,能够在这里截获,比方我们发现跳转到的是一个market的链接,那么我们能够直接跳转到应用市场,或者其它app。





public void onPageStarted(WebView view, String url, Bitmap favicon)

当内核開始载入訪问的url时,会通知应用程序,对每一个main frame这个函数仅仅会被调用一次。页面包括iframe 或者framesets 不会另外调用一次onPageStarted,当网页内内嵌的frame 发生改变时也不会调用onPageStarted。





參数说明:


@param view 接收WebViewClient的那个实例。前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。


@param url    即将要被载入的url


@param favicon 假设这个favicon已经存储在本地数据库中,则会返回这个网页的favicon。否则返回为null。




Tips:


(1) iframe 可能不少人不知道什么含义,这里我解释下。iframe 我们载入的一张,以下有非常多链接,我们随便点击一个链接是即当前host的一个iframe.


(2) 有个问题可能是开发人员困惑的,onPageStarted和shouldOverrideUrlLoading 在网页载入过程中这两个函数究竟哪个先被调用。


     当我们通过loadUrl的方式又一次载入一个网址时候,这时候会先调用onPageStarted再调用shouldOverrideUrlLoading,当我们在打开的这个网址点击一个link,这时候会先调用shouldOverrideUrlLoading 再调用onPageStarted。

只是shouldOverrideUrlLoading不一定每次都被调用。仅仅有须要的时候才会被调用。





public void onPageFinished(WebView view, String url)


当内核载入完当前页面时会通知我们的应用程序。这个函数仅仅有在main frame情况下才会被调用,当调用这个函数之后,渲染的图片不会被更新。假设须要获得新图片的通知能够使用@link WebView.PictureListener#onNewPicture。




參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。


@param url    即将要被载入的url



public void onLoadResource(WebView view, String url)

通知应用程序WebView即将载入url 制定的资源




參数说明:


@param view 接收WebViewClient的那个实例。前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。


@param url    即将载入的url 资源



public WebResourceResponse shouldInterceptRequest(WebView view,
String url)

通知应用程序内核即将载入url制定的资源,应用程序能够返回本地的资源提供给内核。若本地处理返回数据,内核不从网络上获取数据。

參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。


@param url    raw url 制定的资源


@return 返回WebResourceResponse包括数据对象,或者返回null


Tips


这个回调并不一定在UI线程运行,所以我们须要注意在这里操作View或者私有数据相关的动作。


假设我们须要改变网页的背景,或者须要实现网页页面颜色定制化的需求。能够在这个回调时机处理。






public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl)

当浏览器訪问制定的网址错误发生时会通知我们应用程序。比方网络错误。

參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param errorCode 错误号能够在WebViewClient.ERROR_* 里面找到相应的错误名称。

@param description 描写叙述错误的信息


@param failingUrl  当前訪问失败的url,注意并不一定是我们主url




Tips


在onReceiveError我们能够自己定义网页的错误页面。





public void onFormResubmission(WebView view, Message dontResend,
Message resend)

假设浏览器须要又一次发送POST请求,能够通过这个时机来处理。默认是不又一次发送数据。


參数说明:


@param view 接收WebViewClient的那个实例。前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param dontResent 当浏览器不须要又一次发送数据时。能够使用这个參数。

@param resent 当浏览器须要又一次发送数据时, 能够使用这个參数。





public void doUpdateVisitedHistory(WebView view, String url,
boolean isReload)


通知应用程序能够将当前的url存储在数据库中,意味着当前的訪问url已经生效并被记录在内核其中。

这个函数在网页载入过程中仅仅会被调用一次。注意网页前进后退并不会回调这个函数。



參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param url 当前正在訪问的url 

@ param isReload 假设是true 这个是正在被reload的url







public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error)


当网页载入资源过程中发现SSL错误会调用此方法。我们应用程序必须做出响应,是取消请求handler.cancel(),还是继续请求handler.proceed();内核的默认行为是handler.cancel();




參数说明:


@param view 接收WebViewClient的那个实例。前面看到webView.setWebViewClient(new MyAndroidWebViewClient())。即是这个webview。

@param handler 处理用户请求的对象。

@param error  SSL错误对象




Tips


内核会记住本次选择,假设下次还有同样的错误,内核会直接运行之前选择的结果。





public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm)


通知应用程序WebView接收到了一个Http auth的请求,应用程序能够使用supplied 设置webview的响应请求。

默认行为是cancel 本次请求。



參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param handler 用来响应WebView请求的对象

@param host  请求认证的host


@param realm 认真请求所在的域





public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)

提供应用程序同步一个处理按键事件的机会,菜单快捷键须要被过滤掉。

假设返回true,webview不处理该事件,假设返回false, webview会一直处理这个事件,因此在view 链上没有一个父类能够响应到这个事件。默认行为是return false;



參数说明:


@param view 接收WebViewClient的那个实例。前面看到webView.setWebViewClient(new MyAndroidWebViewClient())。即是这个webview。

@param  event 键盘事件名

@return  假设返回true,应用程序处理该时间,返回false 交有webview处理。





public void onScaleChanged(WebView view, float oldScale, float newScale)

通知应用程序webview 要被scale。应用程序能够处理改事件。比方调整适配屏幕。


public void onReceivedLoginRequest(WebView view, String realm,
String account, String args)


通知应用程序有个自己主动登录的帐号过程

參数说明:


@param view 请求登陆的webview


@param realm 账户的域名,用来查找账户。


@param account 一个可选的账户,假设是null 须要和本地的账户进行check, 假设是一个可用的账户,则提供登录。


@param  args  验证制定參数的登录用户




3.WebChromeClient 基本使用




4. WebChromeClient API详细解释


创建WebChromeClient实例并设置到WebView对象中。详细代码參考例如以下:



public void onProgressChanged(WebView view, int newProgress)

通知应用程序当前网页载入的进度。


參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。


public void onReceivedTitle(WebView view, String title)


当document 的title变化时,会通知应用程序


參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param title  document新的title

Tips


这个函数调用时机不确定。有可能非常早。有可能非常晚。取决于网页把title设置在什么位置,大多数网页一般把title设置到页面的前面。因此非常多情况会比較早回调到这个函数。





public void onReceivedIcon(WebView view, Bitmap icon)


当前页面有个新的favicon时候,会回调这个函数。




參数说明:


@param view 接收WebViewClient的那个实例。前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param icon 当前页面的favicon




public void onReceivedTouchIconUrl(WebView view, String url,
boolean precomposed)



通知应用程序 apple-touch-icon的 url 

參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param url  apple-touch-icon 的服务端地址

@param precomposed  假设precomposed 是true 则touch-icon是预先创建的


Tips 


假设应用程序须要这个icon的话, 能够通过这个url获取得到 icon。





public void onShowCustomView(View view, CustomViewCallback callback)


通知应用程序webview须要显示一个custom view,主要是用在视频全屏HTML5Video support。

參数说明:


@param view 即将要显示的view


@param callback  当view 须要dismiss 则使用这个对象进行回调通知。







public void onHideCustomView()

退出视频通知




public boolean onCreateWindow(WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg)

请求创建一个新的窗体。假设我们应用程序接管这个请求,必须返回true,而且创建一个新的webview来承载主窗体。

假设应用程序不处理,则须要返回false。默认行为和返回false表现一样。


參数说明:


@param view 请求创建新窗体的webview


@param isUserGesture 假设是true。则说明是来自用户收拾操作行为。比方用户点击链接


@param isDialog true 请求创建的新窗体必须是个dialog,而不是全屏的窗体。


@param resultMsg 当webview创建时须要发送一个消息。WebView.WebViewTransport.setWebView(WebView)


Tips 详细样例例如以下:



private void createWindow(final Message msg) {
WebView.WebViewTransport transport = (WebView.WebViewTransport) msg.obj;
final Tab newTab = mWebViewController.openTab(null, Tab.this, true,
true);
transport.setWebView(newTab.getWebView());
msg.sendToTarget();
}


public void onRequestFocus(WebView view)

webview请求得到focus。发生这个主要是当前webview不是前台状态。是后台webview。




public void onCloseWindow(WebView window)


通知应用程序从关闭传递过来的webview并从view tree中remove。




public boolean onJsAlert(WebView view, String url, String message,
JsResult result)


通知应用程序显示javascript alert对话框,假设应用程序返回true内核觉得应用程序处理这个消息,返回false,内核自己处理。

參数说明:


@param view 接收WebViewClient的那个实例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是这个webview。

@param url 当前请求弹出javascript 对话框webview 载入的url地址。


@param message 弹出的内容信息


@result 用来响应用户的处理。




Tips


假设我们应用接管处理, 则必须给出result的结果。result.cancel,result.comfirm必须调用其中之后,否则内核会hang住。





public boolean onJsConfirm(WebView view, String url, String message,
JsResult result)


通知应用程序提供confirm 对话框。

參数说明同上onJsAlert





public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, JsPromptResult result)


通知应用程序显示一个prompt对话框。

 


Tips


必须调用result.confirm 方法假设应用程序接管这种方法。





public boolean onJsBeforeUnload(WebView view, String url, String message,
JsResult result)

通知应用程序显示一个对话框,让用户选择是否离开当前页面,这个回调是javascript中的onbeforeunload事件。假设client返回true,内核会觉得client提供对话框。默认行为是return false。

參数说明和之前介绍的onJsAlert()同样。





public void onExceededDatabaseQuota(String url, String databaseIdentifier,
long quota, long estimatedDatabaseSize, long totalQuota,
WebStorage.QuotaUpdater quotaUpdater)


通知应用程序webview内核web sql 数据库超出配额,请求是否扩大数据库磁盘配额。默认行为是不会添加数据库配额。

參数说明:




@param url 触发这个数据库配额的url地址


@param databaseIdentifier  指示出现数据库超过配额的标识。


@param quota   原始数据库配额的大小。是字节单位bytes


@param estimatedDatabaseSize  到达底线的数据大小 bytes


@param totalQuota 总的数据库配额大小 bytes


@param quotaUpdater 更新数据库配额的对象,能够使用 quotaUpdater.updateQuota(newQuota);配置新的数据库配额大小。





public void onReachedMaxAppCacheSize(long requiredStorage, long quota,
WebStorage.QuotaUpdater quotaUpdater)


 通知应用程序内核已经到达最大的appcache。

appcache是HTML5针对offline的一个数据处理标准。





public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback)


当前页面请求是否同意进行定位。



GeolocationPermissions.Callback的使用




public void invoke(String origin, boolean allow, boolean retain);




參数说明:


@param origin 权限设置的源地址


@param allow 是否同意定位


@retain 当前的选择是否让内核记住。





public void onGeolocationPermissionsHidePrompt()


public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture)

这个回调是私有回调。 当页面须要请求打开系统的文件选择器,则会回调这种方法,比方我们须要上传图片。请求拍照。邮件的附件上传等等操作。

假设不实现这个私有API。则上面的请求都将不会运行。




有问题欢迎讨论。