小东子的个人技术专栏

Android中WebView加载本地Html,与JavaScript与Android方法相互传值

最近在做项目中,要使用HightChart来实现心电图,于是,使用WebView加载本地html页面,但是数据是通过蓝牙设备采集的数据,用Java代码获取的数据,需要将数据传到JavaScript中去,使用来绘制心电图。以前都加载服务器端返回的url地址,使用WebView加载,这次不同了,要自己实现心电图的绘制。于是细细的学习了JavaScript与Java代码相互传值,最后总结在这里。

为了让WebView中的JavaScript脚本调用Android方法,WebView提供了一套WebSettings工具类,该工具了提供了大量的方法来管理WebView的选项设置,其中setJavaScriptEnable(true),是让WebView中的JavaScript脚本来调用Android方法。
还有一个最重要的方法addJavaScriptInterface(Object obj,String name)方法,该方法负责把object对象暴漏成JavaScript中的name对象。

1.在WebView调用Android只需要三步

  1. 调用WebView关联的WebSettings中setJavaScriptEnable(true)方法。
  2. 调用WebView关联的WebSettings中addJavaScriptInterface(Object obj,String name)。
  3. 在JavaScript中通过暴露出来的name调用Android中的方法。

1.1首先创建一个Java类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class MyObject {
private Context mContext;
private String data;
private String time;
public MyObject(Context c,String data,String time){
this.data = data;
this.time = time;
mContext = c;
}
/**
* 获取心电数据
* @return
*/
@JavascriptInterface
public String getData(){
String[] dd = new String[0];
try {
dd = data.substring(data.indexOf("Ъ")+2, data.length()-1).split(",");
} catch (Exception e) {
e.printStackTrace();
}
return Arrays.toString(dd).toString();
}
/**
* 获取测量时间
* @return
*/
@JavascriptInterface
public String getTime(){
return time;
}
}

1.2创建在Activity中加载HTML页面

1
2
3
4
5
6
7
8
9
WebSettings wSet =wb .getSettings();
//调用WebView关联的WebSettings中setJavaScriptEnable(true)方法。
wSet.setJavaScriptEnabled(true);
//加载本地HTML页面
wb.loadUrl("file:///android_asset/xd.html");
if (mList != null && mList.size()>0) {
调用WebView关联的WebSettings中addJavaScriptInterface(Object obj,String name)。
wb.addJavascriptInterface(new MyObject(getActivity(), mList.get(0).getResult(),mList.get(0).getDateTime()),"myObj");//这里的myObj是javaScript对象,直接调用getTime()方法,即 myObj.getTime();
}

1.3创建xd.hmtl文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">
<title>心电</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<!--<script src="http://cdn.hcharts.cn/jquery/jquery-1.8.3.min.js"></script>-->
<!--<script src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script>-->
<script type="text/javascript" src="file:///android_asset/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="file:///android_asset/js/highcharts.js"></script>
<script type="text/javascript">
$(function(){
var data = myObj.getData();
var time = myObj.getTime();
dataHighchartXdDt(data,time);
})
//心电
function dataHighchartXdDt(dtxd,t){
//以下是绘制心电的逻辑
//省略
});
}
</script>
<style>
</style>
</head>
<body>
<div class="middlecenter-left-data-top" id="container"></div>
</body>
</html>

注意:

1
2
var data = myObj.getData();
var time = myObj.getTime();

以上第一个方法就是获取心电数据,第二个方法就是获取测量时间。

2.在Android调用JavaScript方法

2.1webView调用js的基本格式为

1
webView.loadUrl(“javascript:methodName(parameterValues)”)

2.2调用js无参无返回值函数

1
2
String call = "javascript:sayHello()";
webView.loadUrl(call);

2.3调用js有参无返回值函数

注意对于字符串作为参数值需要进行转义双引号。

1
2
String call = "javascript:alertMessage("" + "content" + "")";
webView.loadUrl(call);

2.4调用js有参数有返回值的函数

Android在4.4之前并没有提供直接调用js函数并获取值的方法,所以在此之前,常用的思路是 java调用js方法,js方法执行完毕,再次调用java代码将值返回。

2.4.1.Java调用js代码

1
2
String call = "javascript:sumToJava(1,2)";
webView.loadUrl(call);

2.4.2 js函数处理,并将结果通过调用java方法返回

1
2
3
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}

2.4.3.Java在回调方法中获取js函数返回值

1
2
3
4
@JavascriptInterface
public void onSumResult(int result) {
Log.i(LOGTAG, "onSumResult result=" + result);
}

2.5 java代码时用evaluateJavascript方法调用

1
2
3
function getGreetings() {
return 1;
}
1
2
3
4
5
6
7
8
private void testevaluateJavascript(WebView webView) {
webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(LOGTAG, "onReceiveValue value=" + value);
}});
}

输出结果

I/MainActivity( 1432): onReceiveValue value=1
注意

上面限定了结果返回结果为String,对于简单的类型会尝试转换成字符串返回,对于复杂的数据类型,建议以字符串形式的json返回。
evaluateJavascript方法必须在UI线程(主线程)调用,因此onReceiveValue也执行在主线程。

总结,JavaScript与Android方法相互传值,基本上就这么多了。