前言
首先定义定义一段Nativie和Js交互的JS,如String js = "test('test')"
Hybird开发中Nativie和Js交互方式在4.4以下通过webview.loadUrl("javascript:"+js)
或者4.4以下通过webview.evaluateJavascript(js, valueCallback)
进行交互,如果我们的js内容简单,没有特殊字符,比如’\’,’\n’等,我们的交互比较顺利,但是如果要进行交互的字符串含有特殊字符,但我们又没有进行处理,那么js端接受到数据后进行数据解析,就会出现一些特殊异常,比如js端的JSON解析异常Unexpected token d。如下面的是服务端返回的一段json格式的字符串:
String data = "{"status":1,"body":{"message":null,"data":"[{\"dataId\":10008,\"data\":\"{\\\"tName\\\":\\\"CRUD\\\"}}]"}}";
我们不讨论这段格式是否合理,服务端就是这样返回的数据。
我们通过Nativie的http请求服务端返回上述data,这里的有些数据省略了,有些数据还有6个”\”,如果直接webview.loadUrl(“javascript:”+js)方式传输到js端,js接受到数据后在进行JSON解析,直接报错Unexpected token d。
进过多番测试,都没有发现问题,这些数据明明是服务端返回的数据,Nativie层也没有做其他的处理,直接传到js端,怎么解析出错呢。开始怀疑服务端的数据有问题,但是测试发现服务端的数据没有问题;又开始怀疑Nativie端解析有问题,通过JSONObject又能进行解析;并且直接使用js的ajax进行返回的数据js端也能进行解析;一下懵了,怀疑是不是loadUrl的时候webview对数据进行了处理,仔细对比js端收到的数据和Nativie的数据进行比较,发现js端接受的数据少了一些“\“。仔细一想,原来”\”是转义符,在进行String的传输过程中会丢失,比如”\”“,如果不做处理,js端接受到是数据将会变成”\”,但是我们js端想要的是”\”“,所以我们必须在执行loadUrl之前对数据进行处理,解决方法如下:
解决方法
这里主要对字符串进行一些处理:
private static String decode(String value) {
if (TextUtils.isEmpty(value)) {
return value;
}
StringBuilder out = new StringBuilder();
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
switch (c) {
case '"':
case '\'':
case '/':
case '\\':
out.append('\\').append(c);
break;
case '\t':
out.append("\\t");
break;
case '\b':
out.append("\\b");
break;
case '\n':
out.append("\\n");
break;
case '\r':
out.append("\\r");
break;
case '\f':
out.append("\\f");
break;
default:
if (c <= '\037')
out.append(String.format("\\u%04x", new Object[] { Integer.valueOf(c) }));
else {
out.append(c);
}
break;
}
}
return out.toString();
}