Android WebView 与JS的数据交互

关于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控件。代码片段如下:





载入页面:

 

webView = (WebView) findViewById(R.id.webview);
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的支持:

WebSettings setting = webView.getSettings();
setting.setJavaScriptEnabled(true);//支持js

增加对中文的支持:

WebSettings setting = webView.getSettings();
setting.setDefaultTextEncodingName("GBK");//设置字符编码

设置页面滚动条风格:

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

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

 
 
	 
	Page Title 
	
	 

	
	
	
 
 

Page Title

Page content goes here.

Page Footer

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

运行应用后的截图:

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

3.        良好的用户体验

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

webView.setWebChromeClient(new WebChromeClient() {
	public void onProgressChanged(WebView view, int progress) {// 载入进度改变而触发
			if (progress == 100) {
					handler.sendEmptyMessage(1);// 如果全部载入,隐藏进度对话框
			}
				super.onProgressChanged(view, progress);
		}
});

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

 

		handler = new Handler() {
			public void handleMessage(Message msg) {// 定义一个Handler,用于处理下载线程与UI间通讯
				if (!Thread.currentThread().isInterrupted()){
					switch (msg.what) {
					case 0:
						pd.show();// 显示进度对话框
						break;
					case 1:
						pd.hide();// 隐藏进度对话框,不可使用dismiss()、cancel(),否则再次调用show()时,显示的对话框小圆圈不会动。
						break;
					}
				}
				super.handleMessage(msg);
			}
		};

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

 

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

4.        获取java中的数据

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

public class AndroidToastForJs {
	
	private Context mContext;

public AndroidToastForJs(Context context){
		this.mContext = context;
	}
	
//webview中调用toast原生组件
public void showToast(String toast) {
		Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
	}
	
//webview中求和
public int sum(int a,int b){
		return a+b;
	}
	
 //以json实现webview与js之间的数据交互
public String jsontohtml(){
		JSONObject map;
		JSONArray array = new JSONArray();
		try {
			map = new JSONObject();
			map.put("name","aaron");
			map.put("age", 25);
			map.put("address", "中国上海");
			array.put(map);
			
			map = new JSONObject();
			map.put("name","jacky");
			map.put("age", 22);
			map.put("address", "中国北京");
			array.put(map);
			
			map = new JSONObject();
			map.put("name","vans");
			map.put("age", 26);
			map.put("address", "中国深圳");
			map.put("phone","13888888888");
			array.put(map);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return array.toString();
	}
}


 

Webview提供的传入js的方法:

webView.addJavascriptInterface(new AndroidToastForJs(mContext), "JavaScriptInterface");

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

	
 
 

Android via Interface

I'm ,click to see my info

Page Footer

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

你可能感兴趣的:(Android)