Android WebView 与JS的数据交互

简介: 转自 :http://blog.csdn.net/cappuccinolau/article/details/8262821 关于WebView 我们知道目前android市场上的一些应用采用的开发方式大致分为三种:Native App、Web App、Hybrid App。本文主要是Hybrid App中实现的主要技术native组件与js的数据交互的理解以及实现

转自 :http://blog.csdn.net/cappuccinolau/article/details/8262821


关于WebView

我们知道目前android市场上的一些应用采用的开发方式大致分为三种:Native AppWeb AppHybrid App。本文主要是Hybrid App中实现的主要技术native组件与js的数据交互的理解以及实现。

 

Android API中提供了WebView组件来实现对html的渲染。所谓的HybridApp开发方式即是汇集了HTML5CSS3jS的相关开发技术,以及数据交换格式json/XML。这显然是Web开发工程师的技能。正是因为如此,众多中小企业选择了这种开发方式来减少对android开发工程师的过度依赖,至于这三种开发方式的比较与优劣不在本文考虑之列。

 

有了WebView这个组件,Android应用开发技术也就转嫁到htmljava数据交互上来。说白了就是jsWebView的数据交互,这就是本文所要讨论的。

WebViewjs的数据交互

1.        WebView中载入静态页面

 

WebView添加到应用中。和原生控件一样,在layout引入WebView控件。代码片段如下:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/linearLayout"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:background="#000"  
  7.     android:orientation="horizontal" >  
  8. <WebView  
  9.     android:id="@+id/webview"  
  10.     android:layout_width="match_parent"  
  11.     android:layout_height="match_parent"   
  12.     />  
  13. </LinearLayout>  

载入页面:

 

[java]  view plain copy
  1. webView = (WebView) findViewById(R.id.webview);  
  2. webView.loadUrl("file:///file:///android_asset/page.html");  

page.html存储在工程文件的assets根目录下。

2.        引入jquery mobile

引入js框架让我们编写的html页面更接近于原生控件的显示效果。目前主流的移动应用js框架有:jquery mobilesencha touchjquery mobilesencha touch的选型不在本文讨论范围)。本文选择使用jquery mobile

 

首先,在webview添加对js的支持:

[java]  view plain copy
  1. WebSettings setting = webView.getSettings();  
  2. setting.setJavaScriptEnabled(true);//支持js  

增加对中文的支持:

[java]  view plain copy
  1. WebSettings setting = webView.getSettings();  
  2. setting.setDefaultTextEncodingName("GBK");//设置字符编码  

设置页面滚动条风格:

[java]  view plain copy
  1. webView.setScrollBarStyle(0);//滚动条风格,为0指滚动条不占用空间,直接覆盖在网页上  

jquery mobile提供的标准页面模板TemplateForJQuery.html

[html]  view plain copy
  1. <!DOCTYPE html>   
  2. <html>   
  3.     <head>   
  4.     <title>Page Title</title>   
  5.       
  6.     <meta name="viewport" content="width=device-width, initial-scale=1">   
  7.   
  8.     <link rel="stylesheet" href="css/jquery.mobile-1.1.1.min.css" />  
  9.     <script src="js/jquery.js"></script>  
  10.     <script src="js/jquery.mobile-1.1.1.min.js"></script>  
  11. </head>   
  12. <body>   
  13.   
  14. <div data-role="page">  
  15.   
  16.     <div data-role="header">  
  17.         <h1>Page Title</h1>  
  18.     </div><!-- /header -->  
  19.   
  20.     <div data-role="content">   
  21.         <p>Page content goes here.</p>        
  22.     </div><!-- /content -->  
  23.   
  24.     <div data-role="footer">  
  25.         <h4>Page Footer</h4>  
  26.     </div><!-- /footer -->  
  27. </div><!-- /page -->  
  28.   
  29. </body>  
  30. </html>  

页面依赖的js库、css等均放在assets目录下,目录组织结构如下:

运行应用后的截图:

下面是button 的截图,与原生控件没什么明显区别,有种以假乱真的感觉:

3.        良好的用户体验

运行我们的应用发现,在拥有大量js的页面被载入时,一直处于等待中,这是很糟糕的用户体验。可以加入进度条解决。注意到webview提供的两个方法:setWebViewClientsetWebChromeClient。其中setWebChromeClient方法正是可以处理progress的加载,此外,还可以处理js对话框,在webview中显示icon图标等。对于处理progress的代码片段如下:

[java]  view plain copy
  1. webView.setWebChromeClient(new WebChromeClient() {  
  2.     public void onProgressChanged(WebView view, int progress) {// 载入进度改变而触发  
  3.             if (progress == 100) {  
  4.                     handler.sendEmptyMessage(1);// 如果全部载入,隐藏进度对话框  
  5.             }  
  6.                 super.onProgressChanged(view, progress);  
  7.         }  
  8. });  

其中通过handler 消息机制来处理UI线程的更新:

 

[java]  view plain copy
  1. handler = new Handler() {  
  2.     public void handleMessage(Message msg) {// 定义一个Handler,用于处理下载线程与UI间通讯  
  3.         if (!Thread.currentThread().isInterrupted()){  
  4.             switch (msg.what) {  
  5.             case 0:  
  6.                 pd.show();// 显示进度对话框  
  7.                 break;  
  8.             case 1:  
  9.                 pd.hide();// 隐藏进度对话框,不可使用dismiss()、cancel(),否则再次调用show()时,显示的对话框小圆圈不会动。  
  10.                 break;  
  11.             }  
  12.         }  
  13.         super.handleMessage(msg);  
  14.     }  
  15. };  

对于setWebViewClient方法,一般用来处理html的加载(需要重载onPageStarted(WebView view, String url, Bitmap favicon))、关闭(需要重载onPageFinishedWebViewview, String url)方法)。

 

setWebViewClientsetWebChromeClient的作用:前者主要用于处理webView的控制问题,如加载、关闭、错误处理等;后者主要处理js对话框、图标、页面标题等。

4.        获取java中的数据

单独构建一个接口,作为处理jsjava的数据交互的桥梁,本文封装的代码AndroidToastForJs.java如下:

[java]  view plain copy
  1. public class AndroidToastForJs {  
  2.       
  3.     private Context mContext;  
  4.   
  5. public AndroidToastForJs(Context context){  
  6.         this.mContext = context;  
  7.     }  
  8.       
  9. //webview中调用toast原生组件  
  10. public void showToast(String toast) {  
  11.         Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();  
  12.     }  
  13.       
  14. //webview中求和  
  15. public int sum(int a,int b){  
  16.         return a+b;  
  17.     }  
  18.       
  19.  //以json实现webview与js之间的数据交互  
  20. public String jsontohtml(){  
  21.         JSONObject map;  
  22.         JSONArray array = new JSONArray();  
  23.         try {  
  24.             map = new JSONObject();  
  25.             map.put("name","aaron");  
  26.             map.put("age"25);  
  27.             map.put("address""中国上海");  
  28.             array.put(map);  
  29.               
  30.             map = new JSONObject();  
  31.             map.put("name","jacky");  
  32.             map.put("age"22);  
  33.             map.put("address""中国北京");  
  34.             array.put(map);  
  35.               
  36.             map = new JSONObject();  
  37.             map.put("name","vans");  
  38.             map.put("age"26);  
  39.             map.put("address""中国深圳");  
  40.             map.put("phone","13888888888");  
  41.             array.put(map);  
  42.         } catch (JSONException e) {  
  43.             e.printStackTrace();  
  44.         }  
  45.         return array.toString();  
  46.     }  
  47. }  


 

Webview提供的传入js的方法:

[java]  view plain copy
  1. webView.addJavascriptInterface(new AndroidToastForJs(mContext), "JavaScriptInterface");  

Html页面jsonData.html设计的部分代码如下:

[html]  view plain copy
  1.     <script type="text/javascript">  
  2.     var result = JavaScriptInterface.jsontohtml();  
  3.     var obj = eval("("+result+")");//解析json字符串  
  4.     function showAndroidToast(toast)   
  5.     {          
  6.         JavaScriptInterface.showToast(toast);   
  7.     }  
  8.     function getjsonData(){  
  9.         var result = JavaScriptInterface.jsontohtml();  
  10.         var obj = eval("("+result+")");//解析json字符串  
  11.         for(i=0;i<obj.length;i++){  
  12.             var user=obj[i];  
  13.             document.write("<p>姓名:"+user.name+"</p>");  
  14.             document.write("<p>年龄:"+user.age+"</p>");  
  15.             document.write("<p>地址:"+user.address+"</p>");  
  16.             if(user.phone!=null){  
  17.                 document.write("<p>手机号码:"+user.address+"</p>");  
  18.             }  
  19.         }  
  20.     }     
  21.     function list(){  
  22.         document.write("<div data-role='header'><p>another</p></div>");  
  23.     }  
  24.     </script>  
  25. </head>   
  26. <body>   
  27. <div data-role="page" >  
  28.     <div data-role="header" data-theme="c">  
  29.         <h1>Android via Interface</h1>  
  30.     </div><!-- /header -->  
  31.     <div data-role="content">   
  32.         <button value="say hello" onclick="showAndroidToast('Hello,Android!')" data-theme="e"></button>  
  33.         <button value="get json data" onclick="getjsonData()" data-theme="e"></button>    
  34.     </div><!-- /content -->  
  35. <div data-role="collapsible" data-theme="c" data-content-theme="f">  
  36.    <h3>I'm <script>document.write(obj[0].name);</script>,click to see my info</h3>  
  37.    <p><script>document.write("<p>姓名:"+obj[0].name+"</p>");</script></p>  
  38.    <p><script>document.write("<p>年龄:"+obj[0].age+"</p>");</script></p>  
  39.    <p><script>document.write("<p>地址:"+obj[0].address+"</p>");</script></p>  
  40. </div>  
  41.     <div data-role="footer" data-theme="c">  
  42.         <h4>Page Footer</h4>  
  43.     </div><!-- /footer -->  
  44. </div><!-- /page -->  
  45. </body>  

点击say hello按钮运行的截图如下:


目录
相关文章
|
2月前
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
45 0
|
2月前
|
JavaScript 前端开发
JavaScript随手笔记 --- 对数据进行判断最大位数是否超过八位
JavaScript随手笔记 --- 对数据进行判断最大位数是否超过八位
|
3月前
|
存储 前端开发 JavaScript
JavaScript 中的 BLOB 数据结构的使用介绍
JavaScript 中的 BLOB 数据结构的使用介绍
63 1
|
4月前
|
JSON JavaScript 前端开发
JavaScript 如何对 JSON 数据进行冒泡排序?
JavaScript 如何对 JSON 数据进行冒泡排序?
52 0
|
4月前
|
JavaScript 前端开发
NUS CS1101S:SICP JavaScript 描述:二、使用数据构建抽象
NUS CS1101S:SICP JavaScript 描述:二、使用数据构建抽象
29 0
|
3天前
|
XML JSON API
转Android上基于JSON的数据交互应用
转Android上基于JSON的数据交互应用
|
19天前
android-agent-web中js-bridge案例
android-agent-web中js-bridge案例
21 2
|
27天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
12 0
|
27天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
14 0
|
1月前
|
JavaScript
EasyUi js 加载数据进下拉框combobox
EasyUi js 加载数据进下拉框combobox

热门文章

最新文章