Android WebView实践

WebView在混合开发中很重要,如果做纯应用开发的话则很少接触他,这里来梳理一下WebView的知识。

一 基本用法

1.1 Android View的一种用来展示网页

  • 在布局中添加WebView
  • 使用WebView加载网页

1.2 基本组件

  • WebSettings:对WebView做各种设置
1.2.1 JS处理
  • setJavaScriptEnabled(true); //支持js
  • setPluginsEnabled(true); //支持插件
  • setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
1.2.2 缩放处理
  • setUseWideViewPort(true); //将图片调整到适合webview的大小
  • setLoadWithOverviewMode(true); // 缩放至屏幕的大小
  • setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
  • setBuiltInZoomControls(true); //设置内置的缩放控件。 这个取决于setSupportZoom(), 若setSupportZoom(false),则该WebView不可缩放,这个不管设置什么都不能缩放。
  • setDisplayZoomControls(false); //隐藏原生的缩放控件
1.2.3 内容布局
  • setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局
  • supportMultipleWindows(); //多窗口
1.2.4 文件缓存
  • setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
  • setAllowFileAccess(true); //设置可以访问文件
1.2.5 其他设置
  • setNeedInitialFocus(true); //当webview调用requestFocus时为webview设置节点
  • setLoadsImagesAutomatically(true); //支持自动加载图片
  • setDefaultTextEncodingName("utf-8"); //设置编码格式
  • setPluginState(PluginState.OFF); //设置是否支持flash插件
  • setDefaultFontSize(20); //设置默认字体大小
  • WebViewClient:用来帮助WebView处理各种通知, 请求事件。继承它实现定制。
  • shouldOverrideUrlLoading(WebView view, String url) //在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作。比如获取url,查看url.contains(“add”),进行添加操作
  • shouldOverrideKeyEvent(WebView view, KeyEvent event) //处理在浏览器中的按键事件。
  • onPageStarted(WebView view, String url, Bitmap favicon) //开始载入页面时调用的,我们可以设定一个loading的页面,告诉用户程序在等待网络响应。
  • onPageFinished(WebView view, String url) //在页面加载结束时调用, 我们可以关闭loading 条,切换程序动作。
  • onLoadResource(WebView view, String url) //在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
  • onReceivedError(WebView view, int errorCode, String description, String failingUrl) //报告错误信息
  • doUpdateVisitedHistory(WebView view, String url, boolean isReload) //更新历史记录
  • onFormResubmission(WebView view, Message dontResend, Message resend) //应用程序重新请求网页数据
  • onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,String realm) //获取返回信息授权请求
  • onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) //让webview处理https请求。
  • onScaleChanged(WebView view, float oldScale, float newScale) //WebView发生改变时调用
  • onUnhandledKeyEvent(WebView view, KeyEvent event) //Key事件未被加载时调用
  • WebChromeClient:帮助WebView处理JS的对话框、网址图标、网址标题和加载进度等。
  • public void onProgressChanged(WebView view, int newProgress); //获得网页的加载进度,显示在右上角的TextView控件中
  • public void onReceivedTitle(WebView view, String title); //获取Web页中的title用来设置自己界面中的title, 当加载出错的时候,比如无网络,这时onReceiveTitle中获取的标题为"找不到该网页",
  • public void onReceivedIcon(WebView view, Bitmap icon); //获取Web页中的icon
  • public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg);
  • public void onCloseWindow(WebView window);
  • public boolean onJsAlert(WebView view, String url, String message, JsResult result); //处理alert弹出框,html 弹框的一种方式
  • public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) //处理confirm弹出框
  • public boolean onJsConfirm(WebView view, String url, String message, JsResult result); //处理prompt弹出框

生命周期

  • onResume(): WebView为活跃状态时回调,可以正常执行网页的响应。
  • onPause(): WebView被切换到后台时回调, 页面被失去焦点, 变成不可见状态,onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。
  • pauseTimers(): 当应用程序被切换到后台时回调,该方法针对全应用程序的WebView,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
  • resumeTimers(): 恢复pauseTimers时的动作。
  • destroy():关闭了Activity时回调, WebView调用destory时, WebView仍绑定在Activity上.这是由于自定义WebView构建时传入了该Activity的context对象, 因此需要先从父容器中移除WebView, 然后再销毁webview。


页面导航

页面跳转

当我们在WebView点击链接时, 默认的WebView会直接跳转到别的浏览器中, 如果想要实现在WebView内跳转就需要设置WebViewClient

WebView、WebViewClient、WebChromeClient三者的区别
  • WebView: 主要负责解析和渲染网页
  • WebViewClient: 辅助WebView处理各种通知和请求事件
  • WebChromeClient: 辅助WebView处理JavaScript中的对话框, 网址图标和标题等
控制不同链接的跳转方式

继承WebViewClient重写shouldOverrideUrlLoading()方法



方法的两点说明

  • 方法返回值
    返回true: Android 系统会处理URL, 一般是唤起系统浏览器。 返回false: 当前 WebView 处理URL。
  • 方法deprecated问题
    API >= 24时被标记deprecated, 它的替代方法是


页面回退

重写onKeyEvent()方法


页面滑动
  • 三个判断高度的方法
    getScrollY();当前内容滚动的距离
    getHeight(); getBottom();都返回当前WebView这个容器的高度
    getContentHeight(); 整个html的高度, 但并不等同于当前整个页面的高度。因为WebView有缩放功能, 所以当前整个页面的高度实际上应该是原始html的高度 再乘上缩放比例.
  • 判断WebView是否滚动到顶部或底部



    API 17开始, mWebView.getScale()被标记为deprecate,获取新的Scale。


    image
缓存实现
  • 加载html页面时, 会在/data/data/包名目录下生成database与cache两个文件夹。
  • 请求的url记录是保存在WebViewCache.db, 而url的内容是保存在WebViewCache文件夹下。
  • 控制缓存行为


清除缓存

本地资源访问

  • html内容先下载到本地,然后使用loadDataWithBaseURL加载html。这样就可以在html中使用 [file:///android_asset/xxx.png](file:///android_asset/xxx.png)的链接来引用包里 面assets下的资源了。
  • 注意事项
    从网络上下载html的过程应放在工作线程中
    html下载成功后渲染出html的步骤应放在UI主线程,不然WebView会报错
    html下载失败则可以使用我们前面讲述的方法来显示自定义错误界面

二 代码交互

Android原生方案
  • JavaScript代码和Android代码是通过addJavascriptInterface()来建立连接的
1. 设置WebView支持JavaScript
2. webView.getSettings().setJavaScriptEnabled(true);
3. 在Android工程里定义一个接口WebAppInterface
4. API >= 17时, 被JavaScript调用的Android方法前添加@JavascriptInterface注解, 否则将无法识别。
5.  Android代码中将该接口添加到WebView
    webView.addJavascriptInterface(new WebAppInterface(this), "Android");
    "Android"就是我们为这个接口取的别名, 在JavaScript就可以通过Android.showToast(toast)这种方式来调用此方法。
  • 在JavaScript中调用Android方法
    JavaScript中我们不用再去实例化WebAppInterface接口


  • 由于addJavascriptInterface()给予了JS代码控制应用的能力, 这是一项非常有用的特性, 但同时也带来了安全上的隐患,

jockeyjs开源方案

  • jockeyjs是一套IOS/Android双平台的Native和JS交互方法, 比较适合用在项目中
  • jockeyjs对Native和JS的交互做了优美的封装, 事件的发送与接收都可以通过send()和on()来完成。

三 性能优化

  • 优化网页加载速度
    原因:webkit解析网页各个节点,当有图片加载时会影响css或者js文件加载
    解决办法: 设置WebView, 先禁止加载图片



    覆写WebViewClient的onPageFinished()方法, 页面加载结束后再加载图片



    4.4以上系统在onPageFinished时再恢复图片加载时,如果存在多张图片引用的是相同的src时,会只有一个image标签得到加载,因而对于这样的系统我们就先直接加载。
  • 硬件加速页面闪烁问题
    原因:当WebView视图被整体遮住一块,然后突然恢复时(比如使用SlideMenu将WebView从侧边 滑出来时),这个过渡期会出现白块同时界面闪烁。
    解决办法:在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启



    过度后开启硬件加速



以上就是我对webView的总结。

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

推荐阅读更多精彩内容