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。
缓存实现
- 加载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的总结。