You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ac...@apache.org on 2018/01/10 11:26:38 UTC
incubator-weex git commit: [WEEX-130][android] High Performance
Binary Wson Supported
Repository: incubator-weex
Updated Branches:
refs/heads/master 8604d29ef -> 6c2024ae7
[WEEX-130][android] High Performance Binary Wson Supported
[WEEX-130][android] High Performance Binary Wson Supported
close #974
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/6c2024ae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/6c2024ae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/6c2024ae
Branch: refs/heads/master
Commit: 6c2024ae7622f8db606cf43ea850510a9810cd17
Parents: 8604d29
Author: jianbai.gbj <ji...@alibaba-inc.com>
Authored: Mon Dec 11 23:35:24 2017 +0800
Committer: acton393 <zh...@gmail.com>
Committed: Wed Jan 10 19:25:17 2018 +0800
----------------------------------------------------------------------
android/sdk/libs/armeabi/libweexjsb.so | Bin
android/sdk/libs/armeabi/libweexjsc.so | Bin 336796 -> 337420 bytes
android/sdk/libs/armeabi/libweexjss.so | Bin 6758224 -> 6770516 bytes
.../java/com/taobao/weex/WXEnvironment.java | 7 +-
.../java/com/taobao/weex/bridge/WXBridge.java | 16 +-
.../com/taobao/weex/bridge/WXBridgeManager.java | 71 +-
.../java/com/taobao/weex/bridge/WXJSObject.java | 1 +
.../java/com/taobao/weex/common/IWXBridge.java | 7 +-
.../com/taobao/weex/ui/module/WXMetaModule.java | 28 +
.../java/com/taobao/weex/utils/WXJsonUtils.java | 34 +
.../main/java/com/taobao/weex/wson/Wson.java | 776 +++++++++++++++++++
.../taobao/weex/bridge/WXBridgeManagerTest.java | 6 +-
.../com/taobao/weex/bridge/WXBridgeTest.java | 5 +-
13 files changed, 912 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/libs/armeabi/libweexjsb.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/armeabi/libweexjsb.so b/android/sdk/libs/armeabi/libweexjsb.so
old mode 100644
new mode 100755
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/libs/armeabi/libweexjsc.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/armeabi/libweexjsc.so b/android/sdk/libs/armeabi/libweexjsc.so
old mode 100644
new mode 100755
index a7df74c..a16f627
Binary files a/android/sdk/libs/armeabi/libweexjsc.so and b/android/sdk/libs/armeabi/libweexjsc.so differ
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/libs/armeabi/libweexjss.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/armeabi/libweexjss.so b/android/sdk/libs/armeabi/libweexjss.so
old mode 100644
new mode 100755
index 23c14e9..4c7cdda
Binary files a/android/sdk/libs/armeabi/libweexjss.so and b/android/sdk/libs/armeabi/libweexjss.so differ
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
index 4ae572a..79ea1e3 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
@@ -85,7 +85,7 @@ public class WXEnvironment {
public static long sSDKInitTime =0;
public static LogLevel sLogLevel = LogLevel.DEBUG;
- private static boolean isApkDebug = true;
+ private static boolean isApkDebug = false;
public static boolean isPerf = false;
private static String sGlobalFontFamily;
@@ -305,4 +305,9 @@ public class WXEnvironment {
}
}
}
+
+ public static void setApkDebugable(boolean debugable){
+ isApkDebug = debugable;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
index 06fdaf4..8e328fc 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
@@ -27,6 +27,7 @@ import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.WXSDKManager;
import com.taobao.weex.common.IWXBridge;
+import com.taobao.weex.utils.WXJsonUtils;
import com.taobao.weex.utils.WXLogUtils;
/**
@@ -108,7 +109,7 @@ class WXBridge implements IWXBridge {
public int callNative(String instanceId, byte [] tasks, String callback) {
try {
- return callNative(instanceId,new String(tasks),callback);
+ return callNative(instanceId,(JSONArray)WXJsonUtils.parseWson(tasks),callback);
} catch (Throwable e) {
//catch everything during call native.
// if(WXEnvironment.isApkDebugable()){
@@ -118,7 +119,7 @@ class WXBridge implements IWXBridge {
}
}
- public int callNative(String instanceId, String tasks, String callback) {
+ public int callNative(String instanceId, JSONArray tasks, String callback) {
long start = System.currentTimeMillis();
WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(instanceId);
if(instance != null) {
@@ -146,7 +147,7 @@ class WXBridge implements IWXBridge {
}
public int callAddElement(String instanceId, String ref,byte[] dom,String index, String callback) {
try {
- return callAddElement(instanceId,ref,new String(dom),index,callback);
+ return callAddElement(instanceId,ref, (JSONObject) WXJsonUtils.parseWson(dom),index,callback);
} catch (Throwable e) {
WXLogUtils.e(TAG,"callAddElement throw exception:"+e.getMessage());
return 0;
@@ -195,7 +196,7 @@ class WXBridge implements IWXBridge {
/**
* JSF render Node by callAddElement
*/
- public int callAddElement(String instanceId, String ref,String dom,String index, String callback) {
+ public int callAddElement(String instanceId, String ref,JSONObject dom,String index, String callback) {
long start = System.currentTimeMillis();
WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(instanceId);
@@ -248,11 +249,10 @@ class WXBridge implements IWXBridge {
*/
@Override
public Object callNativeModule(String instanceId, String module, String method, byte [] arguments, byte [] options) {
-
- JSONArray argArray = JSON.parseArray(arguments == null ? new String("") : new String(arguments));
+ JSONArray argArray = (JSONArray) WXJsonUtils.parseWson(arguments);
JSONObject optionsObj = null;
if (options != null) {
- optionsObj = JSON.parseObject(options == null ? new String("") :new String(options));
+ optionsObj = (JSONObject) WXJsonUtils.parseWson(options);
}
Object object = WXBridgeManager.getInstance().callNativeModule(instanceId,module,method,argArray,optionsObj);
return new WXJSObject(object);
@@ -268,7 +268,7 @@ class WXBridge implements IWXBridge {
*/
@Override
public void callNativeComponent(String instanceId, String componentRef, String method, byte [] arguments, byte [] options) {
- JSONArray argArray = JSON.parseArray(arguments == null ? new String("") : new String(arguments));
+ JSONArray argArray = (JSONArray)WXJsonUtils.parseWson(arguments);
WXBridgeManager.getInstance().callNativeComponent(instanceId,componentRef,method,argArray,options);
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index 48dfd77..54e0643 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -62,6 +62,7 @@ import com.taobao.weex.utils.WXUtils;
import com.taobao.weex.utils.WXViewUtils;
import com.taobao.weex.utils.batch.BactchExecutor;
import com.taobao.weex.utils.batch.Interceptor;
+import com.taobao.weex.wson.Wson;
import java.io.BufferedReader;
import java.io.File;
@@ -440,8 +441,8 @@ public class WXBridgeManager implements Callback, BactchExecutor {
* @param tasks tasks to be executed
* @param callback next tick id
*/
- public int callNative(String instanceId, String tasks, String callback) {
- if (TextUtils.isEmpty(tasks)) {
+ public int callNative(String instanceId, JSONArray tasks, String callback) {
+ if (tasks == null || tasks.isEmpty()) {
String err = "[WXBridgeManager] callNative: call Native tasks is null";
WXLogUtils.e(err);
WXExceptionUtils.commitCriticalExceptionRT(instanceId,
@@ -465,7 +466,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
long start = System.currentTimeMillis();
long parseNanos = System.nanoTime();
- JSONArray array = JSON.parseArray(tasks);
+ JSONArray array = tasks;
parseNanos = System.nanoTime() - parseNanos;
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
@@ -941,7 +942,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
return IWXBridge.INSTANCE_RENDERING;
}
- public int callAddElement(String instanceId, String ref, String dom, String index, String callback) {
+ public int callAddElement(String instanceId, String ref, JSONObject dom, String index, String callback) {
if (WXEnvironment.isApkDebugable()) {
mLodBuilder.append("[WXBridgeManager] callNative::callAddElement >>>> instanceId:").append(instanceId)
@@ -958,7 +959,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
long start = System.currentTimeMillis();
long nanosTemp = System.nanoTime();
- JSONObject domObject = JSON.parseObject(dom);
+ JSONObject domObject = dom;
nanosTemp = System.nanoTime() - nanosTemp;
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
@@ -971,7 +972,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
if (WXTracing.isAvailable() && addElementAction instanceof TraceableAction) {
((TraceableAction) addElementAction).mParseJsonNanos = nanosTemp;
((TraceableAction) addElementAction).mStartMillis = start;
- ((TraceableAction) addElementAction).onStartDomExecute(instanceId, "addElement", domObject.getString("ref"), domObject.getString("type"), dom);
+ ((TraceableAction) addElementAction).onStartDomExecute(instanceId, "addElement", domObject.getString("ref"), domObject.getString("type"), dom.toString());
}
}
@@ -1130,19 +1131,21 @@ public class WXBridgeManager implements Callback, BactchExecutor {
Object[] tasks = {task};
WXJSObject[] jsArgs = {
new WXJSObject(WXJSObject.String, instanceId),
- new WXJSObject(WXJSObject.JSON,
- WXJsonUtils.fromObjectToJSONString(tasks))};
+ WXJsonUtils.wsonWXJSObject(tasks)};
byte[] taskResult = invokeExecJSWithResult(String.valueOf(instanceId), null, METHOD_CALL_JS, jsArgs, true);
if(eventCallback == null){
return;
}
if(taskResult != null){
- JSONArray arrayResult = JSONArray.parseArray(new String(taskResult, "UTF-8"));
+ JSONArray arrayResult = (JSONArray) WXJsonUtils.parseWson(taskResult);
if(arrayResult != null && arrayResult.size() > 0){
result = arrayResult.get(0);
}
}
eventCallback.onCallback(result);
+ jsArgs[0] = null;
+ taskResult = null;
+ jsArgs = null;
}catch (Exception e){
WXLogUtils.e("asyncCallJSEventWithResult ");
}
@@ -1633,14 +1636,15 @@ public class WXBridgeManager implements Callback, BactchExecutor {
public void invokeExecJS(String instanceId, String namespace, String function,
WXJSObject[] args, boolean logTaskDetail) {
-// if (WXEnvironment.isApkDebugable()) {
- mLodBuilder.append("callJS >>>> instanceId:").append(instanceId)
- .append("function:").append(function);
- if (logTaskDetail)
- mLodBuilder.append(" tasks:").append(WXJsonUtils.fromObjectToJSONString(args));
- WXLogUtils.d(mLodBuilder.substring(0));
- mLodBuilder.setLength(0);
-// }
+ if (WXEnvironment.isApkDebugable()) {
+ mLodBuilder.append("callJS >>>> instanceId:").append(instanceId)
+ .append("function:").append(function);
+ if (logTaskDetail) {
+ mLodBuilder.append(" tasks:").append(argsToJSON(args));
+ }
+ WXLogUtils.d(mLodBuilder.substring(0));
+ mLodBuilder.setLength(0);
+ }
mWXBridge.execJS(instanceId, namespace, function, args);
}
@@ -1649,14 +1653,30 @@ public class WXBridgeManager implements Callback, BactchExecutor {
if (WXEnvironment.isApkDebugable()) {
mLodBuilder.append("callJS >>>> instanceId:").append(instanceId)
.append("function:").append(function);
- if(logTaskDetail)
- mLodBuilder.append(" tasks:").append(WXJsonUtils.fromObjectToJSONString(args));
+ if(logTaskDetail) {
+ mLodBuilder.append(" tasks:").append(argsToJSON(args));
+ }
WXLogUtils.d(mLodBuilder.substring(0));
mLodBuilder.setLength(0);
}
return mWXBridge.execJSWithResult(instanceId, namespace, function, args);
}
+ public @NonNull static String argsToJSON(WXJSObject[] args) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ for(WXJSObject object : args){
+ if(object.type == WXJSObject.WSON){
+ object = new WXJSObject(WXJSObject.WSON, Wson.parse((byte[]) object.data));
+ }
+ builder.append(WXJsonUtils.fromObjectToJSONString(object));
+ builder.append(",");
+ }
+ builder.append("]");
+ return builder.toString();
+ }
+
+
private void invokeInitFramework(Message msg) {
String framework = "";
if (msg.obj != null) {
@@ -1764,7 +1784,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
try {
Object instanceId = message.obj;
- Object task = null;
+ ArrayList<WXHashMap<String, Object>> task = null;
Stack<String> instanceStack = mNextTickTasks.getInstanceStack();
int size = instanceStack.size();
for (int i = size - 1; i >= 0; i--) {
@@ -1774,15 +1794,18 @@ public class WXBridgeManager implements Callback, BactchExecutor {
break;
}
}
- task = ((ArrayList) task).toArray();
+ Object[] tasks = ((ArrayList) task).toArray();
WXJSObject[] args = {
new WXJSObject(WXJSObject.String, instanceId),
- new WXJSObject(WXJSObject.JSON,
- WXJsonUtils.fromObjectToJSONString(task))};
+ WXJsonUtils.wsonWXJSObject(tasks)};
invokeExecJS(String.valueOf(instanceId), null, METHOD_CALL_JS, args);
-
+ task.clear();
+ for(int i=0; i<tasks.length; i++){
+ args[i] = null;
+ }
+ args = null;
} catch (Throwable e) {
WXLogUtils.e("WXBridgeManager", e);
String err = "invokeCallJSBatch#" + WXLogUtils.getStackTrace(e);
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java
index 4c92a70..6101d06 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java
@@ -26,6 +26,7 @@ public class WXJSObject {
public static final int NUMBER = 1;
public static final int String = 2;
public static final int JSON = 3;
+ public static final int WSON = 4;
public Object data;
public int type;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java b/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
index 52e7937..6a2a97f 100644
--- a/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
+++ b/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
@@ -18,6 +18,9 @@
*/
package com.taobao.weex.common;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
import com.taobao.weex.bridge.WXJSObject;
import com.taobao.weex.bridge.WXParams;
@@ -71,9 +74,9 @@ public interface IWXBridge extends IWXObject {
* js call native
*/
- int callNative(String instanceId, String tasks, String callback);
+ int callNative(String instanceId, JSONArray tasks, String callback);
- int callAddElement(String instanceId, String ref,String dom,String index, String callback);
+ int callAddElement(String instanceId, String ref, JSONObject dom, String index, String callback);
void reportJSException(String instanceId, String func, String exception);
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
index 0b89242..7b3eb8d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
@@ -18,14 +18,19 @@
*/
package com.taobao.weex.ui.module;
+import android.app.Application;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.text.TextUtils;
+import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.WXEnvironment;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.common.WXModule;
import com.taobao.weex.utils.WXLogUtils;
+import com.taobao.weex.utils.WXUtils;
import com.taobao.weex.utils.WXViewUtils;
import java.net.URLDecoder;
@@ -62,4 +67,27 @@ public class WXMetaModule extends WXModule {
}
}
}
+
+
+ @JSMethod(uiThread = true)
+ public void openLog(String open) {
+ Application application = WXEnvironment.getApplication();
+ if(application == null){
+ return;
+ }
+ ApplicationInfo info = application.getApplicationInfo();
+ if((info.flags & ApplicationInfo.FLAG_DEBUGGABLE)!= 0){
+ if(WXUtils.getBoolean(open, true)) {
+ WXEnvironment.setApkDebugable(true);
+ if(mWXSDKInstance != null) {
+ Toast.makeText(mWXSDKInstance.getContext(), "log open success", Toast.LENGTH_SHORT).show();
+ }
+ }else{
+ WXEnvironment.setApkDebugable(false);
+ if(mWXSDKInstance != null) {
+ Toast.makeText(mWXSDKInstance.getContext(), "log close success", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/utils/WXJsonUtils.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXJsonUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXJsonUtils.java
index cb8e2a7..a52323f 100644
--- a/android/sdk/src/main/java/com/taobao/weex/utils/WXJsonUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXJsonUtils.java
@@ -25,7 +25,9 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.bridge.WXJSObject;
import com.taobao.weex.common.WXRuntimeException;
+import com.taobao.weex.wson.Wson;
import java.util.ArrayList;
import java.util.List;
@@ -90,4 +92,36 @@ public class WXJsonUtils {
}
}
}
+
+
+ /**
+ * total entry, with wson support, and can degrade to json
+ * */
+ public static final Object parseWson(byte[] data){
+ if(data == null){
+ return null;
+ }
+ try{
+ if(USE_WSON){
+ return Wson.parse(data);
+ }else{
+ return JSON.parse(new String(data, "UTF-8"));
+ }
+ }catch (Exception e){
+ WXLogUtils.e("weex wson parse error ", e);
+ return null;
+ }
+ }
+
+
+ public static final WXJSObject wsonWXJSObject(Object tasks){
+ //CompatibleUtils.checkDiff(tasks);
+ if(USE_WSON) {
+ return new WXJSObject(WXJSObject.WSON, Wson.toWson(tasks));
+ }else{
+ return new WXJSObject(WXJSObject.JSON, WXJsonUtils.fromObjectToJSONString(tasks));
+ }
+ }
+
+ private static final boolean USE_WSON = true;
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/main/java/com/taobao/weex/wson/Wson.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/wson/Wson.java b/android/sdk/src/main/java/com/taobao/weex/wson/Wson.java
new file mode 100644
index 0000000..c9516a7
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/wson/Wson.java
@@ -0,0 +1,776 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.wson;
+
+
+import android.support.v4.util.LruCache;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.utils.WXLogUtils;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * fast binary json format for parse map and serialize map
+ * Created by efurture on 2017/8/16.
+ */
+public class Wson {
+
+ /**
+ * skip map null values
+ * */
+ public static final boolean WriteMapNullValue = false;
+ /**
+ * wson data type
+ * */
+ private static final byte NULL_TYPE = '0';
+
+ private static final byte STRING_TYPE = 's';
+
+ private static final byte BOOLEAN_TYPE_TRUE = 't';
+
+ private static final byte BOOLEAN_TYPE_FALSE = 'f';
+
+ private static final byte NUMBER_INT_TYPE = 'i';
+
+ private static final byte NUMBER_LONG_TYPE = 'l';
+
+ private static final byte NUMBER_BIG_INTEGER_TYPE = 'g';
+
+ private static final byte NUMBER_BIG_DECIMAL_TYPE = 'e';
+
+ private static final byte NUMBER_DOUBLE_TYPE = 'd';
+
+ private static final byte NUMBER_FLOAT_TYPE = 'F';
+
+ private static final byte ARRAY_TYPE = '[';
+
+ private static final byte MAP_TYPE = '{';
+
+ /**
+ * StringUTF-16, byte order with native byte order
+ * */
+ private static final boolean IS_NATIVE_LITTLE_ENDIAN = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
+
+
+ /**
+ * parse wson data to object, please use WXJsonUtils.parseWson
+ * @param data byte array
+ * */
+ public static final Object parse(byte[] data){
+ if(data == null){
+ return null;
+ }
+ try{
+ Parser parser = new Parser(data);
+ Object object = parser.parse();
+ parser.close();
+ return object;
+ }catch (Exception e){
+ WXLogUtils.e("parseWson", e);
+ return null;
+ }
+ }
+
+
+ /**
+ * serialize object to wson data, please use WXJsonUtils.wsonWXJSObject
+ * */
+ public static final byte[] toWson(Object object){
+ if(object == null){
+ return null;
+ }
+ Builder builder = new Builder();
+ byte[] bts = builder.toWson(object);
+ builder.close();
+ return bts;
+ }
+
+
+ /**
+ * wson data parser
+ * */
+ private static final class Parser {
+
+ private int position = 0;
+ private byte[] buffer;
+ private char[] charsBuffer;
+
+ private Parser(byte[] buffer) {
+ this.buffer = buffer;
+ charsBuffer = localCharsBufferCache.get();
+ if(charsBuffer != null){
+ localCharsBufferCache.set(null);
+ }else{
+ charsBuffer = new char[512];
+ }
+ }
+
+
+ private final Object parse(){
+ return readObject();
+ }
+
+ private final void close(){
+ position = 0;
+ buffer = null;
+ if(charsBuffer != null){
+ localCharsBufferCache.set(charsBuffer);
+ }
+ charsBuffer = null;
+ }
+
+ private final Object readObject(){
+ byte type = readType();
+ switch (type){
+ case STRING_TYPE:
+ return readUTF16String();
+ case NUMBER_INT_TYPE :
+ return readVarInt();
+ case NUMBER_FLOAT_TYPE :
+ return readFloat();
+ case MAP_TYPE:
+ return readMap();
+ case ARRAY_TYPE:
+ return readArray();
+ case NUMBER_DOUBLE_TYPE :
+ return readDouble();
+ case NUMBER_LONG_TYPE :
+ return readLong();
+ case NUMBER_BIG_INTEGER_TYPE :
+ return new BigInteger(readUTF16String());
+ case NUMBER_BIG_DECIMAL_TYPE :
+ return new BigDecimal(readUTF16String());
+ case BOOLEAN_TYPE_FALSE:
+ return Boolean.FALSE;
+ case BOOLEAN_TYPE_TRUE:
+ return Boolean.TRUE;
+ case NULL_TYPE:
+ return null;
+ default:
+ throw new RuntimeException("wson unhandled type " + type + " " +
+ position + " length " + buffer.length);
+ }
+ }
+
+
+
+ private final Object readMap(){
+ int size = readUInt();
+ Map<String, Object> object = new JSONObject();;
+ for(int i=0; i<size; i++){
+ String key = readMapKeyUTF16();
+ Object value = readObject();
+ object.put(key, value);
+ }
+ return object;
+ }
+
+ private final Object readArray(){
+ int length = readUInt();
+ List<Object> array = new JSONArray(length);
+ for(int i=0; i<length; i++){
+ array.add(readObject());
+ }
+ return array;
+ }
+
+ private final byte readType(){
+ byte type = buffer[position];
+ position ++;
+ return type;
+ }
+
+
+ private final String readMapKeyUTF16() {
+ int length = readUInt();
+ length = length/2;
+ if(charsBuffer.length < length){
+ charsBuffer = new char[length];
+ }
+ int hash = 5381;
+ if(IS_NATIVE_LITTLE_ENDIAN){
+ for(int i=0; i<length; i++){
+ char ch = (char) ((buffer[position] & 0xFF) +
+ (buffer[position + 1] << 8));
+ charsBuffer[i] = (ch);
+ hash = ((hash << 5) + hash) + ch;
+ position+=2;
+ }
+ }else{
+ for(int i=0; i<length; i++){
+ char ch = (char) ((buffer[position + 1] & 0xFF) +
+ (buffer[position] << 8));
+ charsBuffer[i] = (ch);
+ hash = ((hash << 5) + hash) + ch;
+ position+=2;
+ }
+ }
+ int globalIndex = (globalStringBytesCache.length - 1)&hash;
+ String cache = globalStringBytesCache[globalIndex];
+ if(cache != null
+ && cache.length() == length){
+ boolean isStringEqual = true;
+ for(int i=0; i<length; i++){
+ if(charsBuffer[i] != cache.charAt(i)){
+ isStringEqual = false;
+ break;
+ }
+ }
+ if(isStringEqual) {
+ return cache;
+ }
+ }
+ cache = new String(charsBuffer, 0, length);
+ if(length < 64) {
+ globalStringBytesCache[globalIndex] = cache;
+ }
+ return cache;
+ }
+
+ private final String readUTF16String(){
+ int length = readUInt()/2;
+ if(charsBuffer.length < length){
+ charsBuffer = new char[length];
+ }
+ if(IS_NATIVE_LITTLE_ENDIAN){
+ for(int i=0; i<length; i++){
+ char ch = (char) ((buffer[position] & 0xFF) +
+ (buffer[position + 1] << 8));
+ charsBuffer[i] = (ch);
+ position+=2;
+ }
+ }else{
+ for(int i=0; i<length; i++){
+ char ch = (char) ((buffer[position + 1] & 0xFF) +
+ (buffer[position] << 8));
+ charsBuffer[i] = (ch);
+ position+=2;
+ }
+ }
+ return new String(charsBuffer, 0, length);
+ }
+
+
+
+
+
+ private final int readVarInt(){
+ int raw = readUInt();
+ // This undoes the trick in putVarInt()
+ int num = (((raw << 31) >> 31) ^ raw) >> 1;
+ // This extra step lets us deal with the largest signed values by treating
+ // negative results from read unsigned methods as like unsigned values.
+ // Must re-flip the top bit if the original read value had it set.
+ return num ^ (raw & (1 << 31));
+ }
+
+ private final int readUInt(){
+ int value = 0;
+ int i = 0;
+ int b;
+ while (((b = buffer[position]) & 0x80) != 0) {
+ value |= (b & 0x7F) << i;
+ i += 7;
+ position+=1;
+ if (i > 35) {
+ throw new IllegalArgumentException("Variable length quantity is too long");
+ }
+ }
+ position+=1;
+ return value | (b << i);
+ }
+
+ private final long readLong(){
+ long number = (((buffer[position + 7] & 0xFFL) ) +
+ ((buffer[position + 6] & 0xFFL) << 8) +
+ ((buffer[position + 5] & 0xFFL) << 16) +
+ ((buffer[position + 4] & 0xFFL) << 24) +
+ ((buffer[position + 3] & 0xFFL) << 32) +
+ ((buffer[position + 2] & 0xFFL) << 40) +
+ ((buffer[position + 1] & 0xFFL) << 48) +
+ (((long) buffer[position]) << 56));
+ position += 8;
+ return number;
+ }
+
+ private final double readDouble(){
+ double number = Double.longBitsToDouble(readLong());
+ return number;
+ }
+
+ private Object readFloat() {
+ int number = (((buffer[position + 3] & 0xFF) ) +
+ ((buffer[position + 2] & 0xFF) << 8) +
+ ((buffer[position + 1] & 0xFF) << 16) +
+ ((buffer[position ] & 0xFF) << 24));
+ position +=4;
+ return Float.intBitsToFloat(number);
+ }
+ }
+
+ /**
+ * wson builder
+ * */
+ private static final class Builder {
+
+ private byte[] buffer;
+ private int position;
+ private ArrayList refs;
+ private final static ThreadLocal<byte[]> bufLocal = new ThreadLocal<byte[]>();
+ private final static ThreadLocal<ArrayList> refsLocal = new ThreadLocal<ArrayList>();
+
+
+
+ private Builder(){
+ buffer = bufLocal.get();
+ if(buffer != null) {
+ bufLocal.set(null);
+ }else{
+ buffer = new byte[1024];
+ }
+ refs = refsLocal.get();
+ if(refs != null){
+ refsLocal.set(null);
+ }else{
+ refs = new ArrayList<>(16);
+ }
+ }
+
+
+ private final byte[] toWson(Object object){
+ writeObject(object);
+ byte[] bts = new byte[position];
+ System.arraycopy(buffer, 0, bts, 0, position);
+ return bts;
+ }
+
+ private final void close(){
+ if(buffer.length <= 1024*16){
+ bufLocal.set(buffer);
+ }
+ if(refs.isEmpty()){
+ refsLocal.set(refs);
+ }else{
+ refs.clear();
+ }
+ refs = null;
+ buffer = null;
+ position = 0;
+ }
+
+ private final void writeObject(Object object) {
+ if(object instanceof CharSequence){
+ ensureCapacity(2);
+ writeByte(STRING_TYPE);
+ writeUTF16String((CharSequence) object);
+ return;
+ }else if (object instanceof Map){
+ if(refs.contains(object)){
+ ensureCapacity(2);
+ writeByte(NULL_TYPE);
+ return;
+ }
+ refs.add(object);
+ Map map = (Map) object;
+ writeMap(map);
+ refs.remove(refs.size()-1);
+ return;
+ }else if (object instanceof List){
+ if(refs.contains(object)){
+ ensureCapacity(2);
+ writeByte(NULL_TYPE);
+ return;
+ }
+ refs.add(object);
+ ensureCapacity(8);
+ List list = (List) object;
+ writeByte(ARRAY_TYPE);
+ writeUInt(list.size());
+ for(Object value : list){
+ writeObject(value);
+ }
+ refs.remove(refs.size()-1);
+ return;
+ }else if (object instanceof Number){
+ Number number = (Number) object;
+ writeNumber(number);
+ return;
+ }else if (object instanceof Boolean){
+ ensureCapacity(2);
+ Boolean value = (Boolean) object;
+ if(value){
+ writeByte(BOOLEAN_TYPE_TRUE);
+ }else{
+ writeByte(BOOLEAN_TYPE_FALSE);
+ }
+ return;
+ }else if(object == null){
+ ensureCapacity(2);
+ writeByte(NULL_TYPE);
+ return;
+ }else if (object.getClass().isArray()){
+ if(refs.contains(object)){
+ ensureCapacity(2);
+ writeByte(NULL_TYPE);
+ return;
+ }
+ refs.add(object);
+ ensureCapacity(8);
+ int length = Array.getLength(object);
+ writeByte(ARRAY_TYPE);
+ writeUInt(length);
+ for(int i=0; i<length; i++){
+ Object value = Array.get(object, i);
+ writeObject(value);
+ }
+ refs.remove(refs.size()-1);
+ return;
+ }else if(object instanceof Date){
+ ensureCapacity(10);
+ double date = ((Date)object).getTime();
+ writeByte(NUMBER_DOUBLE_TYPE);
+ writeDouble(date);
+ }else if(object instanceof Calendar){
+ ensureCapacity(10);
+ double date = ((Calendar)object).getTime().getTime();
+ writeByte(NUMBER_DOUBLE_TYPE);
+ writeDouble(date);
+ }else if(object instanceof Collection){
+ if(refs.contains(object)){
+ ensureCapacity(2);
+ writeByte(NULL_TYPE);
+ return;
+ }
+ refs.add(object);
+ ensureCapacity(8);
+ Collection list = (Collection) object;
+ writeByte(ARRAY_TYPE);
+ writeUInt(list.size());
+ for(Object value : list){
+ writeObject(value);
+ }
+ refs.remove(refs.size()-1);
+ }else{
+ if(refs.contains(object)){
+ ensureCapacity(2);
+ writeByte(NULL_TYPE);
+ }else {
+ refs.add(object);
+ writeMap(toMap(object));
+ refs.remove(refs.size()-1);
+ }
+ return;
+ }
+ }
+
+ private final void writeNumber(Number number) {
+ ensureCapacity(12);
+ if(number instanceof Integer){
+ writeByte(NUMBER_INT_TYPE);
+ writeVarInt(number.intValue());
+ return;
+ }
+
+ if(number instanceof Float){
+ writeByte(NUMBER_FLOAT_TYPE);
+ writeFloat(number.floatValue());
+ return;
+ }
+ if(number instanceof Double){
+ writeByte(NUMBER_DOUBLE_TYPE);
+ writeDouble(number.doubleValue());
+ return;
+ }
+
+ if(number instanceof Long){
+ writeByte(NUMBER_LONG_TYPE);
+ writeLong(number.longValue());
+ return;
+ }
+
+ if(number instanceof Short
+ || number instanceof Byte){
+ writeByte(NUMBER_INT_TYPE);
+ writeVarInt(number.intValue());
+ return;
+ }
+
+ if(number instanceof BigInteger){
+ writeByte(NUMBER_BIG_INTEGER_TYPE);
+ writeUTF16String(number.toString());
+ return;
+ }
+
+ if(number instanceof BigDecimal){
+ writeByte(NUMBER_BIG_DECIMAL_TYPE);
+ writeUTF16String(number.toString());
+ return;
+ }
+ writeByte(STRING_TYPE);
+ writeUTF16String(number.toString());
+
+ }
+
+ private final void writeMap(Map map) {
+ if(WriteMapNullValue){
+ ensureCapacity(8);
+ writeByte(MAP_TYPE);
+ writeUInt(map.size());
+ Set<Map.Entry<Object,Object>> entries = map.entrySet();
+ for(Map.Entry<Object,Object> entry : entries){
+ writeMapKeyUTF16(entry.getKey().toString());
+ writeObject(entry.getValue());
+ }
+ }else{
+ Set<Map.Entry<Object,Object>> entries = map.entrySet();
+ int nullValueSize = 0;
+ for(Map.Entry<Object,Object> entry : entries){
+ if(entry.getValue() == null){
+ nullValueSize++;
+ }
+ }
+
+ ensureCapacity(8);
+ writeByte(MAP_TYPE);
+ writeUInt(map.size()-nullValueSize);
+ for(Map.Entry<Object,Object> entry : entries){
+ if(entry.getValue() == null){
+ continue;
+ }
+ writeMapKeyUTF16(entry.getKey().toString());
+ writeObject(entry.getValue());
+ }
+ }
+ }
+
+
+ private final void writeByte(byte type){
+ buffer[position] = type;
+ position++;
+ }
+
+ private final Map toMap(Object object){
+ Map map = new JSONObject();
+ try {
+ Class<?> targetClass = object.getClass();
+ String key = targetClass.getName();
+ List<Method> methods = getBeanMethod(key, targetClass);
+ for (Method method : methods) {
+ String methodName = method.getName();
+ if (methodName.startsWith(METHOD_PREFIX_GET)) {
+ Object value = method.invoke(object);
+ if(value != null){
+ StringBuilder builder = new StringBuilder(method.getName().substring(3));
+ builder.setCharAt(0, Character.toLowerCase(builder.charAt(0)));
+ map.put(builder.toString(), (Object) value);
+ }
+ }else if(methodName.startsWith(METHOD_PREFIX_IS)){
+ Object value = method.invoke(object);
+ if(value != null){
+ StringBuilder builder = new StringBuilder(method.getName().substring(2));
+ builder.setCharAt(0, Character.toLowerCase(builder.charAt(0)));
+ map.put(builder.toString(), value);
+ }
+ }
+ }
+ List<Field> fields = getBeanFields(key, targetClass);
+ for(Field field : fields){
+ String fieldName = field.getName();
+ if(map.containsKey(fieldName)){
+ continue;
+ }
+ Object value = field.get(object);
+ if(value == null){
+ continue;
+ }
+ map.put(fieldName, value);
+ }
+ }catch (Exception e){
+ throw new RuntimeException(e);
+ }
+ return map;
+ }
+
+ private final void writeMapKeyUTF16(String value){
+ writeUTF16String(value);
+ }
+
+
+
+
+ /**
+ * writeString UTF-16
+ * */
+ private final void writeUTF16String(CharSequence value){
+ int length = value.length();
+ ensureCapacity(length*2 + 8);
+ writeUInt(length*2);
+ if(IS_NATIVE_LITTLE_ENDIAN){
+ for(int i=0; i<length; i++){
+ char ch = value.charAt(i);
+ buffer[position] = (byte) (ch);
+ buffer[position+1] = (byte) (ch >>> 8);
+ position+=2;
+ }
+ }else{
+ for(int i=0; i<length; i++){
+ char ch = value.charAt(i);
+ buffer[position + 1] = (byte) (ch );
+ buffer[position] = (byte) (ch >>> 8);
+ position+=2;
+ }
+ }
+ }
+
+
+ private final void writeDouble(double value){
+ writeLong(Double.doubleToLongBits(value));
+ }
+
+ private final void writeFloat(float value){
+ int val = Float.floatToIntBits(value);
+ buffer[position + 3] = (byte) (val );
+ buffer[position + 2] = (byte) (val >>> 8);
+ buffer[position + 1] = (byte) (val >>> 16);
+ buffer[position ] = (byte) (val >>> 24);
+ position += 4;
+ }
+
+ private final void writeLong(long val){
+ buffer[position + 7] = (byte) (val );
+ buffer[position + 6] = (byte) (val >>> 8);
+ buffer[position + 5] = (byte) (val >>> 16);
+ buffer[position + 4] = (byte) (val >>> 24);
+ buffer[position + 3] = (byte) (val >>> 32);
+ buffer[position + 2] = (byte) (val >>> 40);
+ buffer[position + 1] = (byte) (val >>> 48);
+ buffer[position ] = (byte) (val >>> 56);
+ position += 8;
+ }
+
+ private final void writeVarInt(int value){
+ writeUInt((value << 1) ^ (value >> 31));
+ }
+
+ private final void writeUInt(int value){
+ while ((value & 0xFFFFFF80) != 0) {
+ buffer[position] = (byte)((value & 0x7F) | 0x80);
+ position++;
+ value >>>= 7;
+ }
+ buffer[position] = (byte)(value & 0x7F);
+ position++;
+ }
+
+
+ private final void ensureCapacity(int minCapacity) {
+ minCapacity += position;
+ // overflow-conscious code
+ if (minCapacity - buffer.length > 0){
+ int oldCapacity = buffer.length;
+ int newCapacity = oldCapacity << 1;
+ if(newCapacity < 1024*16){
+ newCapacity = 1024*16;
+ }
+ if (newCapacity - minCapacity < 0) {
+ newCapacity = minCapacity;
+ }
+ buffer = Arrays.copyOf(buffer, newCapacity);
+ }
+ }
+ }
+
+
+ /**
+ * cache json property key, most of them all same
+ * */
+ private static final int GLOBAL_STRING_CACHE_SIZE = 2*1024;
+ private static final ThreadLocal<char[]> localCharsBufferCache = new ThreadLocal<>();
+ private static final String[] globalStringBytesCache = new String[GLOBAL_STRING_CACHE_SIZE];
+
+
+
+
+ /**
+ * lru cache, to map helper
+ * */
+ private static final String METHOD_PREFIX_GET = "get";
+ private static final String METHOD_PREFIX_IS = "is";
+ private static LruCache<String, List<Method>> methodsCache = new LruCache<>(128);
+ private static LruCache<String, List<Field>> fieldsCache = new LruCache<>(128);
+
+
+ private static final List<Method> getBeanMethod(String key, Class targetClass){
+ List<Method> methods = methodsCache.get(key);
+ if(methods == null){
+ methods = new ArrayList<>();
+ Method[] allMethods = targetClass.getMethods();
+ for(Method method : allMethods){
+ if(method.getDeclaringClass() == Object.class){
+ continue;
+ }
+ if( (method.getModifiers() & Modifier.STATIC) != 0){
+ continue;
+ }
+ String methodName = method.getName();
+ if(methodName.startsWith(METHOD_PREFIX_GET)
+ || methodName.startsWith(METHOD_PREFIX_IS)) {
+ methods.add(method);
+ }
+ }
+ methodsCache.put(key, methods);
+ }
+ return methods;
+ }
+
+
+
+ private static final List<Field> getBeanFields(String key, Class targetClass){
+ List<Field> fieldList = fieldsCache.get(key);
+ if(fieldList == null) {
+ Field[] fields = targetClass.getFields();
+ fieldList = new ArrayList<>(fields.length);
+ for(Field field : fields){
+ if((field.getModifiers() & Modifier.STATIC) != 0){
+ continue;
+ }
+ fieldList.add(field);
+ }
+ fieldsCache.put(key, fieldList);
+ }
+ return fieldList;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeManagerTest.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeManagerTest.java b/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeManagerTest.java
index bc3e6ae..43f0f16 100644
--- a/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeManagerTest.java
+++ b/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeManagerTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertTrue;
import android.os.Handler;
import android.os.Message;
+
+import com.alibaba.fastjson.JSON;
import com.taobao.weappplus_sdk.BuildConfig;
import com.taobao.weex.InitConfig;
import com.taobao.weex.WXSDKEngine;
@@ -106,12 +108,12 @@ public class WXBridgeManagerTest {
public void testCallNative() throws Exception {
getInstance()
.callNative(instance.getInstanceId(),
- "[{\"module\":\"testModule\",\"method\":\"test\"}]",
+ JSON.parseArray("[{\"module\":\"testModule\",\"method\":\"test\"}]"),
null);
getInstance()
.callNative(instance.getInstanceId(),
- "[{\"module\":\""+WXDomModule.WXDOM+"\",\"method\":\"test\"}]",
+ JSON.parseArray("[{\"module\":\""+WXDomModule.WXDOM+"\",\"method\":\"test\"}]"),
null);
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6c2024ae/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeTest.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeTest.java b/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeTest.java
index 13feaf6..198a90d 100644
--- a/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeTest.java
+++ b/android/sdk/src/test/java/com/taobao/weex/bridge/WXBridgeTest.java
@@ -18,6 +18,7 @@
*/
package com.taobao.weex.bridge;
+import com.alibaba.fastjson.JSON;
import com.taobao.weappplus_sdk.BuildConfig;
import org.junit.After;
import org.junit.Before;
@@ -46,12 +47,12 @@ public class WXBridgeTest {
@Test
public void testCallNative() throws Exception {
- bridge.callNative("1","{}","100");
+ bridge.callNative("1", JSON.parseArray("[]"),"100");
}
@Test
public void testCallAddElement() throws Exception {
- bridge.callAddElement("1","1","{}","0","100");
+ bridge.callAddElement("1","1", JSON.parseObject("{}"),"0","100");
}