深入理解Android—WebView

转自:http://blog.csdn.net/zouzhigang96/article/details/48649979?ref=myread


正文

作为Android开发者 ,我们都知道安卓手机上内置了一款高性能的webkit内核浏览器,在android SDK中封装了一个叫WebView的控件。

在应用开发过程中我们应该需要注意几点:

1.在AndroidManifest.xml文件中添加相应的权限。

2.如果访问的页面中有JavaScript,则需要设置webview 支持JavaScript。

 

  1. WebView.getSettings().setJavaScriptEnabled(true);  


3.如果页面中链接,希望点击链接继续在当前的浏览器中响应,而不是重新打开android系统的browser中响应该链接,必须覆盖WebView的WebViewClient对象。

  1. mWebView.setWebViewClient(new WebViewClient(){  
  2.     public boolean shouldOverrideUrlLoading(WebView view, String url){   
  3.         view.loadUrl(url);  
  4.         return true;  
  5.     }  
  6. });  

4. 如果不做任何处理,浏览页面, 点击系统“Back”键,整个Browser会调用finish()方法来结束自身,如果希望浏览的页面回退而不是推出整个浏览器,需要在当前的Activity中处理并消费掉当前Back事件。
  1. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  2.     if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {   
  3.         mWebView.goBack();  
  4.         return true;  
  5.     }  
  6.     return super.onKeyDown(keyCode, event);  
  7. }  

与JS交互

既然可以显示网页,那么当前也是可以让网页操作本地方法。

  1. public class WebViewDemo extends Activity {   
  2.     private WebView mWebView;  
  3.     private Handler mHandler = new Handler();   
  4.       
  5.     public void onCreate(Bundle icicle) {   
  6.   
  7.     setContentView(R.layout.WebViewdemo);  
  8.     mWebView = (WebView) findViewById(R.id.WebView);   
  9.     WebSettings webSettings = mWebView.getSettings();   
  10.     webSettings.setJavaScriptEnabled(true);   
  11.     mWebView.addJavascriptInterface(new Object() {  
  12.       public void clickOnAndroid() {  
  13.           mHandler.post(new Runnable() {  
  14.               public void run() {   
  15.                   mWebView.loadUrl("javascript:wave()");  
  16.               }  
  17.           });  
  18.       }  
  19.     }, "demo");   
  20.     mWebView.loadUrl("file:///android_asset/demo.html");   
  21.       
  22.     }  
  23. }  

我们看到 addJavascriptInterface(Object obj,String interfaceName) 这个方法,该方法将一个Java对象绑定到一个JavaScript对象中,JavaScript对象名就是 interfaceName(demo) ,作用域是Global,这样初始化了WebView后, 在WebView加载的页面中就可以直接通过JavaScript:window.demo访问到绑定的Java对象, 来看看HTML 中是怎么调用的。

  1. <html>  
  2. <script language="javascript">  
  3.   function wave() {  
  4.     document.getElementById("droid").src="android_waving.png";  
  5.   }  
  6. </script>  
  7. <body>  
  8.   <a onClick="window.demo.clickOnAndroid()">  
  9.   <img id="droid" src="android_normal.png" mce_src="android_normal.png"/><br> Click me! </a>  
  10. </body>  
  11. </html>  

这样在JavaScript中就可以调用Java对象的clickOnAndroid()方法了, 同样我们可以在此对象中定义很多方法(比如:发短信,调用联系人列表等系统功能)。

需要说明一点:addJavascriptInterface()方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他线程中, 这也是使用Handle的目的。


深入使用WebView

让JS调用android代码

1.首先简书一下WebView,WebViewClient , WebChromeClient 之间的区别。

WebView的设计中, 不是什么事都要WebView类来做的,有些杂事是分给其他人的,这样WebView专心做好自己的解析渲染工作就行了,WebViewClient 就是帮助WebView来处理各种通知,请求事件等,WebChromeClient 是辅助WebView处理JavaScript的对话框,网站图标,网站标题,


2.功能实现:

 利用android中的webview 加载一个HTML网页,网页中自定义一个按钮,点击按钮弹出一个Toast.


3.实现步骤:

首先定义一个接口类,将上下文对象传进去,在接口类中定义要在 js 中实现的方法。
接着在assets资源包下定义一个 html 文件,在文件中定义一个 button.button 的点击事件定义为一个 js 函数. 
之后在 xml 中定义一个 WebView 组件,在活动类中获取 WebView 并对 WebView 参数进行设置,此处特别注意要设置 WebView 支持 js 且将定义的 js 接口类添加到 WebView 中去,此后在 js 中就可以利用该接口类中定义的 函数了.即:

  1. myWebView.getSettings().setJavaScriptEnabled(true);  
  2. myWebView.addJavascriptInterface(new JavaScriptinterface(this),”android”);  

最后利用 WebView 加载本地 html 文件的方法是:

  1. myWebView.loadData(htmlText,"text/html""utf-8");  

此处的htmltext 是以字符串的方式读取 assets 报下 html中的内容.


4. 实现利用返回键返回到上一页:
设置 WebView 的按键监听,监听到期返回键并判断网页是否能够返回 ,利用 WebView 的 goBack()返回到上一页.


WebView 缓存

在项目中使用到Webview 控件,当加载HTML页面时, 会在/data/data/应用包名目录下生成database 和 cache 两个文件夹。

请求的URL 记录是保存在WebViewCache.db , 而URL的内容是保存在WebViewCache文件夹下。


WebView 删除缓存

其实已经知道缓存的目录保存位置后, 那么删除就很简单了, 获取到这个缓存,然后删除就OK了。

// 删除保存在手机上的缓存。

  1. private int clearCacheFolder(File dir,long numDays) {   
  2.   int deletedFiles = 0;  
  3.   if (dir!= null && dir.isDirectory()){  
  4.     try {  
  5.       for (File child:dir.listFiles()){  
  6.           if (child.isDirectory()) {  
  7.             deletedFiles += clearCacheFolder(child, numDays);  
  8.         }  
  9.         if (child.lastModified() < numDays) {  
  10.           if (child.delete()) {  
  11.            deletedFiles++;   
  12.           }  
  13.         }  
  14.       }  
  15.     } catch(Exception e) {  
  16.       e.printStackTrace();   
  17.     }  
  18.   }  
  19.   return deletedFiles;   
  20. }  

是否启用缓存功能也是可以控制的:

  1. <span style="white-space:pre">    </span>//优先使用缓存:   
  2.     WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);   
  3.     //不使用缓存:   
  4.     WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);  

在退出应用的时候加上如下代码, 可以完整的清空缓存。
  1. File file = CacheManager.getCacheFileBaseDir();  
  2.     if (file != null && file.exists() && file.isDirectory()) {  
  3.         for (File item : file.listFiles()) {  
  4.             item.delete();  
  5.         }  
  6.         file.delete();  
  7.     }  
  8.     context.deleteDatabase("WebView.db");   
  9.     context.deleteDatabase("WebViewCache.db");  

WebView 处理404错误

显示网页有时候会遇到一个问题, 就是网页有可能会找不到, WebView当然也是可以处理的。

  1. public class WebView_404 extends Activity {   
  2.     private Handler handler = new Handler() {  
  3.     public void handleMessage(Message msg) {  
  4.       if(msg.what==404) {//主页不存在  
  5.         //载入本地 assets 文件夹下面的错误提示页面 404.html   
  6.         web.loadUrl("file:///android_asset/404.html");  
  7.       }else{  
  8.         web.loadUrl(HOMEPAGE);  
  9.       }  
  10.     }  
  11.     };  
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.       web.setWebViewClient(new WebViewClient() {  
  15.     public boolean shouldOverrideUrl(WebView view,String url) {   
  16.         if(url.startsWith("http://") && getRespStatus(url)==404) {  
  17.           view.stopLoading();  
  18.           //载入本地 assets 文件夹下面的错误提示页面 404.html   
  19.           view.loadUrl("file:///android_asset/404.html");  
  20.         }else{  
  21.           view.loadUrl(url);  
  22.         }  
  23.           return true;  
  24.         }  
  25.       });  
  26.       new Thread(new Runnable() {  
  27.     public void run() {  
  28.           Message msg = new Message();  
  29.           //此处判断主页是否存在,因为主页是通过 loadUrl 加载的,  
  30.           //此时不会执行 shouldOverrideUrlLoading 进行页面是否存在的判断 //进入主页后,点主页里面的链接,链接<span style="white-space:pre">         </span>到其他页面就一定会执行  
  31.           shouldOverrideUrlLoading 方法了   
  32.           if(getRespStatus(HOMEPAGE)==404) {  
  33.           msg.what = 404;  
  34.           }  
  35.           handler.sendMessage(msg);  
  36.       }).start();  
  37.   }  
  38. }  



判断WebView是否已经滚动到页面底部

在view中有一个getScrollY()方法, 可以返回当前可见区域的顶端距整个页面的距离, 也就是当前内容滚动的距离。

还有getHeight() 或者 getBottom() 方法 都可以返回当前View 这个容器的高度。

在View 中还有getContentHeight()方法来返回整个Html 页面的高度,但,并不等于就是当前整个页面的高度,因为WebView有缩放功能, 你可以设置如下代码来启动或者关闭webview的缩放功能。


  1. <span style="font-size:18px;">mWebView.getSettings().setSupportZoom(true);  
  2. mWebView.getSettings().setBuiltInZoomControls(true);</span>  


所以当前整个页面的高度实际上应该就是原始HTML的高度再乘以缩放比例,因此更正之后的结果,准确的判断方法应该就是:

  1. // 如果已经处于底端  
  2. if(WebView.getContentHeight*WebView.getScale() -(webvi ew.getHeight()+WebView.getScrollY())){   
  3.   //XXX  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值