You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ha...@apache.org on 2017/10/10 13:48:32 UTC

[13/15] incubator-weex git commit: async layout and preload cell and quick convert parameter

async layout and preload cell and quick convert parameter


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/a17eb2c6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/a17eb2c6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/a17eb2c6

Branch: refs/heads/website
Commit: a17eb2c6859999261889ec08cf519d0b9ed4996e
Parents: b9015dd
Author: jianbai.gbj <ji...@alibaba-inc.com>
Authored: Thu Sep 28 16:32:50 2017 +0800
Committer: Hanks <zh...@gmail.com>
Committed: Tue Oct 10 21:42:52 2017 +0800

----------------------------------------------------------------------
 .../java/com/taobao/weex/dom/WXDomObject.java   |   3 +
 .../com/taobao/weex/dom/WXTextDomObject.java    |   3 +-
 .../weex/ui/component/binding/Layouts.java      | 101 ++++++++++++------
 .../weex/ui/component/binding/Statements.java   |  26 ++++-
 .../list/template/TemplateViewHolder.java       |   4 +
 .../list/template/WXRecyclerTemplateList.java   | 103 +++++++++++++++++--
 .../taobao/weex/utils/WXReflectionUtils.java    |   6 ++
 7 files changed, 197 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
index c766e35..001545d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
@@ -438,6 +438,9 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
       mAttributes = new WXAttr();
     }
     mAttributes.putAll(attrs);
+    if(hasNewLayout()){
+       markUpdateSeen();
+    }
     super.dirty();
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
index 06c4e8a..3456bde 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
@@ -41,6 +41,7 @@ import android.text.style.AlignmentSpan;
 import android.text.style.ForegroundColorSpan;
 import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.common.Constants;
+import com.taobao.weex.common.WXThread;
 import com.taobao.weex.dom.flex.CSSConstants;
 import com.taobao.weex.dom.flex.CSSNode;
 import com.taobao.weex.dom.flex.FloatUtil;
@@ -185,7 +186,7 @@ public class WXTextDomObject extends WXDomObject {
     hasBeenMeasured = false;
     if (layout != null && !layout.equals(atomicReference.get()) &&
         Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-      if(Looper.getMainLooper().getThread().getId() != Thread.currentThread().getId()){
+      if(Thread.currentThread() instanceof WXThread){
           warmUpTextLayoutCache(layout);
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
index f80bc1e..5b8d32c 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
@@ -21,60 +21,40 @@ package com.taobao.weex.ui.component.binding;
 
 
 import android.os.AsyncTask;
-import android.speech.tts.Voice;
+import android.util.Log;
 
+import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.WXSDKInstance;
+import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.dom.flex.CSSLayoutContext;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.ui.component.list.template.TemplateViewHolder;
+import com.taobao.weex.utils.WXLogUtils;
 
 /**
  * Created by furture on 2017/8/21.
  */
 public class Layouts {
     /**
-     * do dom layout, and set layout to component
+     * do dom layout async or sync , and set layout to component on main.
+     * on first use do sync layout, when compontnet reuse do async layout
      * */
-    public static void doLayout(final TemplateViewHolder templateViewHolder){
-        final CSSLayoutContext layoutContext = templateViewHolder.getLayoutContext();
+    public static void doLayoutAsync(final TemplateViewHolder templateViewHolder){
         final WXComponent component = templateViewHolder.getComponent();
-        final WXSDKInstance instance = component.getInstance();
         final  int position = templateViewHolder.getHolderPosition();
         if(templateViewHolder.asyncTask != null){
             templateViewHolder.asyncTask.cancel(true);
+            templateViewHolder.asyncTask = null;
         }
         AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
                 if(templateViewHolder.getHolderPosition() == position){
-
-                    WXDomObject domObject = (WXDomObject) component.getDomObject();
-                    domObject.traverseTree(new WXDomObject.Consumer() {
-                        @Override
-                        public void accept(WXDomObject dom) {
-                            if(instance == null || instance.isDestroy()){
-                                return;
-                            }
-                            if(!dom.hasUpdate()){
-                                return;
-                            }
-                            dom.layoutBefore();
-                        }
-                    });
-                    domObject.calculateLayout(layoutContext);
-                    domObject.traverseTree( new WXDomObject.Consumer() {
-                        @Override
-                        public void accept(WXDomObject dom) {
-                            if(instance == null || instance.isDestroy()){
-                                return;
-                            }
-                            if (dom.hasUpdate()) {
-                                dom.layoutAfter();
-                            }
-                        }
-                    });
+                    if(component.getInstance() != null && !component.getInstance().isDestroy()) {
+                        doSafeLayout(component, templateViewHolder.getLayoutContext());
+                    }
                 }
                 return null;
             }
@@ -82,14 +62,69 @@ public class Layouts {
             @Override
             protected void onPostExecute(Void aVoid) {
                 if(position == templateViewHolder.getHolderPosition()) {
-                    setLayout(component, false);
+                    if(component.getInstance() != null && !component.getInstance().isDestroy()) {
+                        setLayout(component, false);
+                    }
                 }
             }
         };
         templateViewHolder.asyncTask = asyncTask;
-        asyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+        asyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); //serial executor is better
+
     }
 
+    /**
+     * safe layout
+     * */
+    public static void doSafeLayout(WXComponent component, final  CSSLayoutContext layoutContext){
+        try{
+            long start = System.currentTimeMillis();
+            doLayout(component, layoutContext);
+            if(WXEnvironment.isApkDebugable()){
+                WXLogUtils.d("WXTemplateList",
+                        component.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_TYPE) + Thread.currentThread().getName() +  " doSafeLayout  used " +
+                                (System.currentTimeMillis() - start));
+            }
+        }catch (Exception e){
+            if(WXEnvironment.isApkDebugable()){
+                WXLogUtils.e("WXTemplateListdoSafeLayout",  e);
+            }
+        }
+    }
+
+    private static void doLayout(WXComponent component, final  CSSLayoutContext layoutContext){
+        WXDomObject domObject = (WXDomObject) component.getDomObject();
+        final WXSDKInstance instance = component.getInstance();
+        domObject.traverseTree(new WXDomObject.Consumer() {
+            @Override
+            public void accept(WXDomObject dom) {
+                if(instance == null || instance.isDestroy()){
+                    return;
+                }
+                if(!dom.hasUpdate()){
+                    return;
+                }
+                dom.layoutBefore();
+            }
+        });
+        if(instance != null && !instance.isDestroy()){
+            domObject.calculateLayout(layoutContext);
+        }
+        domObject.traverseTree( new WXDomObject.Consumer() {
+            @Override
+            public void accept(WXDomObject dom) {
+                if(instance == null || instance.isDestroy()){
+                    return;
+                }
+                if (dom.hasUpdate()) {
+                    dom.layoutAfter();
+                }
+            }
+        });
+    }
+
+
+
 
     /**
      * recursive set layout to component,

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
index 755bae2..6912335 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
@@ -18,21 +18,26 @@
  */
 package com.taobao.weex.ui.component.binding;
 
+import android.os.Looper;
 import android.support.v4.util.ArrayMap;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXAttr;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.dom.WXEvent;
 import com.taobao.weex.dom.binding.ELUtils;
 import com.taobao.weex.dom.binding.WXStatement;
+import com.taobao.weex.dom.flex.CSSLayoutContext;
 import com.taobao.weex.el.parse.ArrayStack;
 import com.taobao.weex.el.parse.Operators;
 import com.taobao.weex.el.parse.Token;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXComponentFactory;
+import com.taobao.weex.ui.component.WXImage;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.utils.WXLogUtils;
 import com.taobao.weex.utils.WXUtils;
@@ -198,9 +203,11 @@ public class Statements {
                                 renderNodeDomObject.getAttrs().setStatement(null); // clear node's statement
                                 parentDomObject.add(renderNodeDomObject, renderIndex);
                                 parent.addChild(renderNode, renderIndex);
-                                parent.createChildViewAt(renderIndex);
-                                renderNode.applyLayoutAndEvent(renderNode);
-                                renderNode.bindData(renderNode);
+                                if(Thread.currentThread() == Looper.getMainLooper().getThread()) {
+                                    parent.createChildViewAt(renderIndex);
+                                    renderNode.applyLayoutAndEvent(renderNode);
+                                    renderNode.bindData(renderNode);
+                                }
                             }
                             doBindingAttrsEventAndRenderChildNode(renderNode, domObject, context);
                             renderIndex++;
@@ -307,8 +314,17 @@ public class Statements {
             }
 
             if(dynamic.size() > 0) {
-                domObject.updateAttr(dynamic);
-                component.updateProperties(dynamic);
+                if(dynamic.size() == 1
+                        && dynamic.get(Constants.Name.SRC) != null
+                        && component instanceof WXImage){
+                    //for image avoid dirty layout, only update src attrs
+                    domObject.getAttrs().put(Constants.Name.SRC, dynamic.get(Constants.Name.SRC));
+                }else {
+                    domObject.updateAttr(dynamic); //dirty layout
+                }
+                if(Thread.currentThread() == Looper.getMainLooper().getThread()) {
+                    component.updateProperties(dynamic);
+                }
             }
         }
         WXEvent event = domObject.getEvents();

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateViewHolder.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateViewHolder.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateViewHolder.java
index 21930eb..a418e3e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateViewHolder.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateViewHolder.java
@@ -67,6 +67,10 @@ public class TemplateViewHolder extends ListBaseViewHolder {
         return layoutContext;
     }
 
+    public void setLayoutContext(CSSLayoutContext layoutContext){
+        this.layoutContext = layoutContext;
+    }
+
 
     public int getHolderPosition() {
         return holderPosition;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
index 0454aba..5d23bf6 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
@@ -22,6 +22,7 @@ import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Looper;
 import android.support.annotation.NonNull;
@@ -53,6 +54,7 @@ import com.taobao.weex.dom.WXCellDomObject;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.dom.WXEvent;
 import com.taobao.weex.dom.WXRecyclerDomObject;
+import com.taobao.weex.dom.flex.CSSLayoutContext;
 import com.taobao.weex.dom.flex.Spacing;
 import com.taobao.weex.el.parse.ArrayStack;
 import com.taobao.weex.ui.component.AppearanceHelper;
@@ -82,6 +84,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import static com.taobao.weex.common.Constants.Name.LOADMOREOFFSET;
 
@@ -135,7 +138,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
     private Map<String, WXCell> mTemplates;
     private String  listDataTemplateKey = Constants.Name.Recycler.SLOT_TEMPLATE_TYPE;
     private Runnable listUpdateRunnable;
-
+    private ConcurrentHashMap<String, WXCell> mTemplatesCache;
+    private ConcurrentHashMap<String, Boolean> mTemplateRendered;
 
     /**
      * sticky helper
@@ -177,12 +181,20 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         mTemplateViewTypes = new ArrayMap<>();
         mTemplateViewTypes.put("", 0); //empty view, when template was not sended
         mTemplates = new HashMap<>();
+        mTemplatesCache = new ConcurrentHashMap<>();
         mStickyHelper = new TemplateStickyHelper(this);
         cellLifecycleManager = new CellLifecycleManager(this);
         orientation = mDomObject.getOrientation();
         listDataTemplateKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_TEMPLATE_KEY), Constants.Name.Recycler.SLOT_TEMPLATE_TYPE);
         listDataItemKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_ITEM), listDataItemKey);
         listDataIndexKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_ITEM_INDEX), listDataIndexKey);
+        if( getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA) instanceof  JSONArray) {
+            JSONArray array = (JSONArray)getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA);
+            if(array.size() > 0) {
+                listData = array;
+            }
+        }
+        mTemplateRendered = new ConcurrentHashMap<>();
     }
 
     @Override
@@ -204,6 +216,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         }
         RecyclerViewBaseAdapter recyclerViewBaseAdapter = new RecyclerViewBaseAdapter<>(this);
         recyclerViewBaseAdapter.setHasStableIds(true);
+        bounceRecyclerView.getInnerView().setItemAnimator(null);
         bounceRecyclerView.getInnerView().setItemViewCacheSize(itemViewCacheSize);
         bounceRecyclerView.getInnerView().setHasFixedSize(hasFixedSize);
         bounceRecyclerView.setRecyclerViewBaseAdapter(recyclerViewBaseAdapter);
@@ -533,7 +546,13 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                 Object templateId = child.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_TYPE);
                 String key = WXUtils.getString(templateId, null);
                 if(key != null){
+                    //set visible false, skip layout in dom thread, set visible true in onCreateViewHolder
+                    if(child.getDomObject() != null) {
+                        WXDomObject domObject = (WXDomObject) child.getDomObject();
+                        domObject.setVisible(false);
+                    }
                     mTemplates.put(key, (WXCell) child);
+                    asyncPreloadCellCopyCache(key);
                     if(mTemplateViewTypes.get(key) == null){
                         mTemplateViewTypes.put(key, mTemplateViewTypes.size());
                     }
@@ -1017,8 +1036,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         if(WXEnvironment.isApkDebugable()){
             WXLogUtils.d(TAG, position + getTemplateKey(position) + " onBindViewHolder render used " + (System.currentTimeMillis() - start));
         }
-
-        Layouts.doLayout(templateViewHolder);
+        Layouts.doLayoutAsync(templateViewHolder);
         cellLifecycleManager.onAttach(position, component);
         if(WXEnvironment.isApkDebugable()){
             WXLogUtils.d(TAG,  position + getTemplateKey(position) + " onBindViewHolder layout used " + (System.currentTimeMillis() - start));
@@ -1034,30 +1052,95 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
             view.setLayoutParams(new FrameLayout.LayoutParams(0, 0));
             return new TemplateViewHolder(view, viewType);
         }
-        WXCell component = (WXCell) Statements.copyComponentTree(source);
-        if(component.getDomObject() instanceof  WXCellDomObject
-                && getDomObject() instanceof  WXRecyclerDomObject){
-            WXCellDomObject domObject = (WXCellDomObject) component.getDomObject();
-            domObject.setRecyclerDomObject((WXRecyclerDomObject) getDomObject());
+        long start = System.currentTimeMillis();
+        WXCell component = mTemplatesCache.remove(template);
+        boolean needLayout = false;
+        if(component == null) {
+            component = (WXCell) copyCell(source);
+            needLayout = true;
+        }
+        asyncPreloadCellCopyCache(template);
+        CSSLayoutContext layoutContext = null;
+        if(needLayout){
+            layoutContext = new CSSLayoutContext();
+            Layouts.doSafeLayout(component, layoutContext);
+            if(WXEnvironment.isApkDebugable()){
+                WXLogUtils.d(TAG, template + " onCreateViewHolder sync layout used " + (System.currentTimeMillis() - start));
+            }
         }
+        Layouts.setLayout(component, false);
         component.lazy(false);
-        long start = System.currentTimeMillis();
         component.createView();
         if(WXEnvironment.isApkDebugable()){
             WXLogUtils.d(TAG, template + " onCreateViewHolder view used " + (System.currentTimeMillis() - start));
         }
         component.applyLayoutAndEvent(component);
         if(WXEnvironment.isApkDebugable()) {
-            WXLogUtils.d(TAG, template +  " onCreateViewHolder layout used " + (System.currentTimeMillis() - start));
+            WXLogUtils.d(TAG, template +  " onCreateViewHolder apply layout used " + (System.currentTimeMillis() - start));
         }
         component.bindData(component);
         if(WXEnvironment.isApkDebugable()) {
             WXLogUtils.d(TAG, template + " onCreateViewHolder bindData used " + (System.currentTimeMillis() - start));
         }
         TemplateViewHolder templateViewHolder = new TemplateViewHolder(component, viewType);
+        templateViewHolder.setLayoutContext(layoutContext);
         return  templateViewHolder;
     }
 
+    private void asyncPreloadCellCopyCache(final String template) {
+        final WXCell cell = mTemplates.get(template);
+        if(cell == null){
+            return;
+        }
+        if(mTemplatesCache.get(template) != null){
+            return;
+        }
+        AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
+            @Override
+            public void run() {
+                if(cell.getInstance() == null || cell.getInstance().isDestroy()){
+                    return;
+                }
+                WXCell component = (WXCell) copyCell(cell);
+                if(cell.getInstance() == null || cell.getInstance().isDestroy()){
+                    return;
+                }
+                Layouts.doSafeLayout(component, new CSSLayoutContext());
+                mTemplatesCache.put(template, component);
+            }
+        });
+    }
+
+    /**
+     * copy cell component from source, and return source
+     * */
+    private WXComponent copyCell(WXComponent  cell){
+        /** pre render for cell */
+        Boolean rendered = mTemplateRendered.get(cell.getRef());
+        if(rendered == null || !rendered) {
+            if(listData != null){
+                for(int i=0; i<listData.size(); i++){
+                    WXCell source = getSourceTemplate(i);
+                    if(source == cell){
+                        Statements.doRender(cell, getStackContextForPosition(i));
+                        mTemplateRendered.put(source.getRef(), true);
+                        break;
+                    }
+                }
+            }
+        }
+        WXCell component = (WXCell) Statements.copyComponentTree(cell);
+        if(component.getDomObject() != null){
+            ((WXDomObject)component.getDomObject()).setVisible(true);
+        }
+        if(component.getDomObject() instanceof  WXCellDomObject
+                && getDomObject() instanceof  WXRecyclerDomObject){
+            WXCellDomObject domObject = (WXCellDomObject) component.getDomObject();
+            domObject.setRecyclerDomObject((WXRecyclerDomObject) getDomObject());
+        }
+        return component;
+    }
+
     /**
      * @param position
      * when template not send, return an invalid id, use empty view holder.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a17eb2c6/android/sdk/src/main/java/com/taobao/weex/utils/WXReflectionUtils.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXReflectionUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXReflectionUtils.java
index 930c383..5bef6d3 100644
--- a/android/sdk/src/main/java/com/taobao/weex/utils/WXReflectionUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXReflectionUtils.java
@@ -20,6 +20,8 @@ package com.taobao.weex.utils;
 
 import android.text.TextUtils;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -39,6 +41,10 @@ public class WXReflectionUtils {
       return value.getClass().isAssignableFrom(double.class) ? value : WXUtils.getDouble(value);
     } else if (paramClazz == float.class) {
       return value.getClass().isAssignableFrom(float.class) ? value : WXUtils.getFloat(value);
+    } else if (paramClazz == JSONArray.class && value != null && value.getClass() == JSONArray.class) {
+      return  value;
+    } else if (paramClazz == JSONObject.class && value != null && value.getClass() == JSONObject.class) {
+      return  value;
     } else {
       return JSON.parseObject(value instanceof String ? (String) value : JSON.toJSONString(value), paramClazz);
     }