(转载)Android WebView 开发详解(二)

转载请注明出处 http://blog.csdn.net/typename/article/details/39495409 powered by miechal zhao

概览:

Android WebView 做为承载网页的载体控件,他在网页显示的过程中会产生一些事件,并回调给我们的应用程序,以便我们在网页加载过程中做应用程序想处理的事情。比如说客户端需要显示网页加载的进度、网页加载发生错误等等事件。 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 基本使用

  1. 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事件,如果客户端返回true,内核会认为客户端提供对话框。默认行为是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,则上面的请求都将不会执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容