Android Webview基础
来源:互联网 发布:apache for mac下载 编辑:程序博客网 时间:2024/05/17 01:00
Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”和“Web App跨平台开发的优势”,鉴于现在App应用需要对市场快速响应的需求,在Native中嵌入Webview的页面越来越被广泛的使用。本系列文章将从webview的基础,webview的原生接入,webview jsbridge(本系列打算介绍四种),webview安全,webview的优化五个维度来和大家一起对webview进行深入的剖析。
Android的SDK集成了WebView组件,也是View中的一种,它继承自AbsoluteLayout,展示网页的同时,也可以在其中放入其他的子View。从Android 4.4(KitKat)开始,原本基于WebKit的WebView开始基于Chromium内核,这一改动大大提升了WebView组件的性能以及对HTML5,CSS3,JavaScript的支持,同时修复了安全漏洞(Webview安全会详细讲解)。下面对Webview的基础知识进项详细介绍:
一、WebView加载:
(1)加载一个网页:
webView.loadUrl(“http://www.baidu.com/“);
(2)加载apk包中的一个html页面
webView.loadUrl(“file:///android_asset/my.html”);
此处有一个类似的场景:
当我们在WebView中加载出从web服务器上拿取的内容时,是无法访问本地资源的,如assets目录下的图片资源,因为这样的行为属于跨域行为(Cross-Domain),而WebView是禁止的。解决这个问题的方案是把html内容先下载到本地,然后用loadDataWithBaseURL加载html。这样就可以在html中使用 file:///android_asset/xxx.png 的链接来引用包里
面assets下的资源了。
private void loadWithAccessLocal(final String htmlUrl) { //从网络上下载html的过程应放在工作线程中 new Thread(new Runnable() { public void run() { try { final String htmlStr = NetService.getHtml(htmlUrl); if (htmlStr != null) { //html下载成功后渲染出html的步骤应放在UI主线程,不然WebView会报错 TaskExecutor.runTaskOnUiThread(new Runnable() { @Override public void run() { loadDataWithBaseURL(htmlUrl, htmlStr, "text/html", "UTF-8", ""); } }); return; } } catch (Exception e) { Log.e("Exception:" + e.getMessage()); } //html下载失败可以自定义错误界面 TaskExecutor.runTaskOnUiThread(new Runnable() { @Override public void run() { onPageLoadedError(-1, "html get failed"); } }); } }).start();}
(3)加载手机本地的一个html页面的方法:
webView.loadUrl(“content://com.android.html/sdcard/my.html”);
二、WebView基本组件:WebSettings、WebViewClient、WebChromeClient,它们的作用如下:
WebView: 主要负责解析和渲染网页
WebViewClient: 辅助WebView处理各种通知和请求事件
WebChromeClient: 用来辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等。
(1)WebSettings可以对WebView做如下设置:
(2)我们通过继承WebViewClient并重载它的方法可以实现不同功能的定制,如下所示(不贴图了,一页放不下):
private WebViewClient mWebViewClient = new WebViewClient(){ //在网页上的所有加载都经过这个方法,可以在此函数中做一些定制化的修改,比如获取url,查看url.equals(“xxx”) @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //打开网页时不调用系统浏览器, 在本WebView中显示最新的url view.loadUrl(url); return true; } //重写此方法处理在浏览器中的按键事件。 @Override public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) { //个性化处理 return true; } //Key事件未被加载时调用 @Override public void onUnhandledKeyEvent(WebView view, KeyEvent event) { //个性化处理 } //开始载入页面调用,可以设定一个loading的页面,告诉用户程序在等待网络响应。 @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { //个性化处理 } //在页面加载结束时调用,我们可以配合上面效果关闭loading条,切换程序动作。 @Override public void onPageFinished(WebView view, String url) { //个性化处理 } // 在加载页面资源时会调用,每一个资源(图片)的加载都会调用一次。 @Override public void onLoadResource(WebView view, String url) { //个性化处理 } //错误信息报告 @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { //个性化处理 } //webview发生改变时调用 @Override public void onScaleChanged(WebView view, float oldScale, float newScale) { //个性化处理 } //更新历史记录 @Override public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) { //个性化处理 } //应用程序重新请求 @Override public void onFormResubmission(WebView view, Message dontResend, Message resend) { //个性化处理 } //重写此方法让Webview可以处理https请求 @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { //个性化处理 } //获取返回信息授权请求 @Override public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { //个性化处理 } }; //把自定义的mWebViewClient设置给mWebView mWebView.setWebViewClient(mWebViewClient );
(3)通过继承WebChromeClient并重载它的方法也可以实现不同功能的定制,如下图所示:
WebChromeClient mWebChromeClient = new WebChromeClient() { //获得网页的加载进度,显示在右上角的TextView控件中,例如右上角可以显示一个Loading @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress < 100) { //自定义 } else { //自定义 } } //获取Web页中的title用来设置自己界面中的title,但当加载出错的时候,比如无网络,这时onReceiveTitle中获取的标题为 找不到该网页, //因此建议当触发onReceiveError时,不要使用获取到的title @Override public void onReceivedTitle(WebView view, String title) { //自定义 } @Override public void onReceivedIcon(WebView view, Bitmap icon) { //自定义 } @Override public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { //自定义 return true; } @Override public void onCloseWindow(WebView window) { } //alert弹出框 @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { //自定义 return true; } //处理confirm弹出框 @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { //自定义 return true; } //处理prompt弹出框 @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { //自定义 return true; } }; //把自定义的mWebChromeClient设置给mWebView mWebView.setWebChromeClient(mWebChromeClient);
三、WebView页面导航
(1)页面跳转:在WebView点击链接时, 默认的WebView会直接跳转到别的浏览器中, 如果想要实现在WebView内跳转就需要设置WebViewClient。如下所示:
mWebView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); //返回true: Android 系统会处理URL, 一般是唤起系统浏览器。 //返回false: 当前 WebView 处理URL。 return true; } });
(2)页面回退和前进:点击系统返回键同时判断webview是否可以回退,进行不同的逻辑处理
@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) { myWebView.goBack(); return true; }else{ ... } return super.onKeyDown(keyCode, event);}
其他相关方法:
goBack () //后退goForward ()//前进//以当前的index为起始点前进或者后退到历史记录中指定的steps,如果steps为负数则为后退,正数则为前进goBackOrForward (int steps)canGoForward () //是否可以前进canGoBack () //是否可以后退
(3)页面滑动:关于页面滑动, 我们在做下拉刷新等功能时, 经常会去判断WebView是否滚动到顶部或者滚动到底部。请关注一下如下方法:
getScrollY() //方法返回的是当前可见区域的顶端距整个页面顶端的距离,也就是当前内容滚动的距离.getHeight()或者getBottom() //方法都返回当前WebView 这个容器的高度getContentHeight() 返回的是整个html 的高度,但并不等同于当前整个页面的高度,因为WebView 有缩放功能, 所以当前整个页面的高度实际上应该是原始html 的高度再乘上缩放比例. 因此,更正后的结果,准确的判断方法应该是:if (webView.getContentHeight() * webView.getScale() == (webView.getHeight() + webView.getScrollY())) { //已经处于底端 } if(webView.getScrollY() == 0){ //处于顶端 }
四、WebView的状态
onResume () //激活WebView为活跃状态,能正常执行网页的响应onPause () //当页面被失去焦点被切换到后台不可见状态,需要执行onPause动过, onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。pauseTimers () //当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。resumeTimers () //恢复pauseTimers时的动作。destroy () //销毁,关闭了Activity时,音乐或视频,还在播放。就必须销毁。
但是注意:
webview调用destory时,webview仍绑定在Activity上.这是由于自定义webview构建时传入了该Activity的context对象,因此需要先从父容器中移除webview,然后再销毁webview。
rootLayout.removeView(webView); webView.destroy();
五、WebView Cache && Cookie:在项目中如果使用到WebView控件, 当加载html页面时, 会在/data/data/包名目录下生成database与cache两个文件夹。请求的url记录是保存在WebViewCache.db, 而url的内容是保存在WebViewCache文件夹下。
(1)控制缓存行为,如下:
WebSettings webSettings = mWebView.getSettings();//优先使用缓存webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //只在缓存中读取webSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);/不使用缓存WwebSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
清除缓存操作如下:
clearCache(true); //清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.clearHistory (); //清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.clearFormData () //这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。
(2)添加Cookie:
if (!DevUtil.hasLOLLIPOP()) { CookieSyncManager.createInstance(mContext); }CookieManager cookieManager = CookieManager.getInstance();cookieManager.setAcceptCookie(true);List<String> cookies = getCookies(customCookies);//项目中所使用到的所有cookie,因项目而异for (String cookie : cookies) { cookieManager.setCookie(uri.getHost(), cookie);}if (DevUtil.hasLOLLIPOP()) { cookieManager.flush(); } else { CookieSyncManager.getInstance().sync(); }
清除cookie:
CookieManager.getInstance().removeSessionCookie();
- android WebView基础教材
- Android WebView使用基础
- Android WebView使用基础
- Android WebView使用基础
- android WebView基础使用
- Android WebView使用基础
- Android WebView使用基础
- Android基础之WebView
- android基础--WebView
- Android WebView使用基础
- Android:WebView基础
- [Android基础] WebView
- Android WebView使用基础
- Android WebView使用基础
- Android WebView使用基础
- [Android基础] WebView
- Android WebView使用基础
- Android基础之WebView
- Java数组asList()使用方法总结
- spoj 11404 Save Thy Toys
- java对象的强引用,软引用,弱引用和虚引用
- http长轮询&短轮询
- 终端 setting up cocoapods master repo 不动
- Android Webview基础
- event-log-tags
- pdf怎样进行编辑并拆分页面
- Android中所涉及的常用设计模式
- 命令模式:如何用TortoiseSVN,将主干更新的代码合并到本地分支
- Linux基本命令之解压缩
- ssh认证的流程与攻击防范
- python 笔记(2)——Terminal命令
- git保存用户名密码的方法