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");
   }