Repository: incubator-weex
Updated Branches:
  refs/heads/master d01f1086a -> 641e3826e


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java 
b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
index a75092d..114f084 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -63,6 +63,7 @@ import com.taobao.weex.common.WXRequest;
 import com.taobao.weex.common.WXResponse;
 import com.taobao.weex.dom.WXEvent;
 import com.taobao.weex.http.WXHttpUtil;
+import com.taobao.weex.layout.ContentBoxMeasurement;
 import com.taobao.weex.performance.WXAnalyzerDataTransfer;
 import com.taobao.weex.tracing.WXTracing;
 import com.taobao.weex.ui.action.GraphicActionAddElement;
@@ -188,6 +189,8 @@ public class WXSDKInstance implements 
IWXActivityStateListener,View.OnLayoutChan
   private ComponentObserver mComponentObserver;
   private Map<String, GraphicActionAddElement> inactiveAddElementAction = new 
ArrayMap<>();
 
+  private Map<String, ContentBoxMeasurement> mContentBoxMeasurements = new 
ArrayMap<>();
+
   /**
    * set make weexCore run in single process mode
    * @param flag true means weexCore run in single process mode or multi 
process mode
@@ -1378,6 +1381,9 @@ public class WXSDKInstance implements 
IWXActivityStateListener,View.OnLayoutChan
       if(templateRef != null){
         templateRef = null;
       }
+      if (null != mContentBoxMeasurements) {
+        mContentBoxMeasurements.clear();
+      }
       mWXPerformance.afterInstanceDestroy(mInstanceId);
 
       WXBridgeManager.getInstance().post(new Runnable() {
@@ -1939,4 +1945,12 @@ public class WXSDKInstance implements 
IWXActivityStateListener,View.OnLayoutChan
       });
     }
   }
+
+  public void addContentBoxMeasurement(String ref, ContentBoxMeasurement 
contentBoxMeasurement) {
+    mContentBoxMeasurements.put(ref, contentBoxMeasurement);
+  }
+
+  public ContentBoxMeasurement getContentBoxMeasurement(String ref) {
+    return mContentBoxMeasurements.get(ref);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/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 a9f6730..c4b7aed 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
@@ -62,8 +62,9 @@ public class WXBridge implements IWXBridge {
 
   private native void nativeTakeHeapSnapshot(String filename);
 
-  private native void nativeBindMeasurementToWXCore(String instanceId, String 
ref, ContentBoxMeasurement contentBoxMeasurement);
-  private native void nativeBindMeasurementToRenderObject(long ptr, 
ContentBoxMeasurement contentBoxMeasurement);
+  private native void nativeBindMeasurementToRenderObject(long ptr);
+
+  private native void nativeBindMeasurementToWXCore(String instanceId, String 
ref);
 
   private native void nativeSetRenderContainerWrapContent(boolean wrap, String 
instanceId);
 
@@ -456,13 +457,26 @@ public class WXBridge implements IWXBridge {
   }
 
   @Override
-  public void bindMeasurementToWXCore(String instanceId, String ref, 
ContentBoxMeasurement contentBoxMeasurement) {
-    nativeBindMeasurementToWXCore(instanceId, ref, contentBoxMeasurement);
+  public void bindMeasurementToWXCore(String instanceId, String ref) {
+    nativeBindMeasurementToWXCore(instanceId, ref);
+  }
+
+  @Override
+  public ContentBoxMeasurement getMeasurementFunc(String instanceId, String 
ref) {
+    ContentBoxMeasurement obj = null;
+    try {
+      obj = WXBridgeManager.getInstance().getMeasurementFunc(instanceId, ref);
+    } catch (Throwable e) {
+      if (WXEnvironment.isApkDebugable()) {
+        WXLogUtils.e(TAG, "getMeasurementFunc throw exception:" + 
e.getMessage());
+      }
+    }
+    return obj;
   }
 
   @Override
-  public void bindMeasurementToRenderObject(long ptr, ContentBoxMeasurement 
contentBoxMeasurement){
-    nativeBindMeasurementToRenderObject(ptr, contentBoxMeasurement);
+  public void bindMeasurementToRenderObject(long ptr){
+    nativeBindMeasurementToRenderObject(ptr);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/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 4415fd7..f8cc404 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
@@ -2601,12 +2601,21 @@ public class WXBridgeManager implements Callback, 
BactchExecutor {
     return IWXBridge.INSTANCE_RENDERING;
   }
 
-  public void bindMeasurementToWXCore(String instanceId, String ref, 
ContentBoxMeasurement contentBoxMeasurement) {
-    mWXBridge.bindMeasurementToWXCore(instanceId, ref, contentBoxMeasurement);
+  public void bindMeasurementToWXCore(String instanceId, String ref) {
+    mWXBridge.bindMeasurementToWXCore(instanceId, ref);
   }
 
-  public void bindMeasurementToRenderObject(long ptr, ContentBoxMeasurement 
contentBoxMeasurement){
-    mWXBridge.bindMeasurementToRenderObject(ptr, contentBoxMeasurement);
+  public ContentBoxMeasurement getMeasurementFunc(String instanceId, String 
ref) {
+    ContentBoxMeasurement contentBoxMeasurement = null;
+    WXSDKInstance instance = 
WXSDKManager.getInstance().getSDKInstance(instanceId);
+    if (instance != null) {
+      contentBoxMeasurement = instance.getContentBoxMeasurement(ref);
+    }
+    return contentBoxMeasurement;
+  }
+
+  public void bindMeasurementToRenderObject(long ptr){
+    mWXBridge.bindMeasurementToRenderObject(ptr);
   }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/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 725f32b..092a5f3 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
@@ -153,9 +153,11 @@ public interface IWXBridge extends IWXObject {
 
   int callHasTransitionPros(String instanceId, String ref, HashMap<String, 
String> styles);
 
-  void bindMeasurementToWXCore(String instanceId, String ref, 
ContentBoxMeasurement contentBoxMeasurement);
+  void bindMeasurementToWXCore(String instanceId, String ref);
 
-  void bindMeasurementToRenderObject(long ptr, ContentBoxMeasurement 
contentBoxMeasurement);
+  ContentBoxMeasurement getMeasurementFunc(String instanceId, String ref);
+
+  void bindMeasurementToRenderObject(long ptr);
 
   void setRenderContainerWrapContent(boolean wrap, String instanceId);
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/android/sdk/src/main/java/com/taobao/weex/ui/action/BasicComponentData.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/action/BasicComponentData.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/action/BasicComponentData.java
index e70af17..9d12450 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/action/BasicComponentData.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/action/BasicComponentData.java
@@ -90,32 +90,34 @@ public class BasicComponentData<T extends View> {
   }
 
   public final void addShorthand(float[] shorthand, CSSShorthand.TYPE type) {
+    if (shorthand == null) {
+      shorthand = new float[] {0, 0, 0, 0};
+    }
     if (shorthand.length == 4) {
       switch (type) {
         case MARGIN:
-          if(mMargins == null){
+          if (mMargins == null) {
             mMargins = new CSSShorthand(shorthand);
-          }
-          else{
+          } else {
             mMargins.replace(shorthand);
           }
           break;
         case PADDING:
-          if(mPaddings == null){
+          if (mPaddings == null) {
             mPaddings = new CSSShorthand(shorthand);
-          }
-          else{
+          } else {
             mPaddings.replace(shorthand);
           }
           break;
         case BORDER:
-          if(mBorders == null){
+          if (mBorders == null) {
             mBorders = new CSSShorthand(shorthand);
-          }
-          else{
+          } else {
             mBorders.replace(shorthand);
           }
           break;
+        default:
+          break;
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
index e5a7660..94f4848 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
@@ -220,9 +220,10 @@ public abstract class WXComponent<T extends View> extends 
WXBasicComponent imple
     mType = component.getType();
   }
 
-  protected void setContentBoxMeasurement(final ContentBoxMeasurement 
contentBoxMeasurement) {
+  protected final void setContentBoxMeasurement(final ContentBoxMeasurement 
contentBoxMeasurement) {
     this.contentBoxMeasurement = contentBoxMeasurement;
-    
WXBridgeManager.getInstance().bindMeasurementToRenderObject(getRenderObjectPtr(),
 contentBoxMeasurement);
+    mInstance.addContentBoxMeasurement(getRef(), contentBoxMeasurement);
+    
WXBridgeManager.getInstance().bindMeasurementToRenderObject(getRenderObjectPtr());
   }
 
   public void updateStyles(WXComponent component) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/weex_core/Source/CMakeLists.txt b/weex_core/Source/CMakeLists.txt
index 93e9d1f..d2d41d7 100644
--- a/weex_core/Source/CMakeLists.txt
+++ b/weex_core/Source/CMakeLists.txt
@@ -60,6 +60,7 @@ if (ANDROID)
     ./android/base/base64/modp_base64/modp_b64.cc
     ./android/base/string/scoped_jstring.cpp
     ./android/base/string/scoped_jstring_utf8.cpp
+    ./android/base/string/jstring_cache.cpp
     ./android/bridge/impl/bridge_impl_android.cpp
     ./android/bridge/impl/weexcore_impl_android.cpp
     ./android/bridge/impl/measure_mode_impl_android.cpp

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/base/string/jstring_cache.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/string/jstring_cache.cpp 
b/weex_core/Source/android/base/string/jstring_cache.cpp
new file mode 100644
index 0000000..13044f4
--- /dev/null
+++ b/weex_core/Source/android/base/string/jstring_cache.cpp
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+#include <iostream>
+#include "jstring_cache.h"
+
+void JStringCache::clearRefCache(JNIEnv *env) {
+    for (auto iter = cacheList.begin(); iter != cacheList.end(); iter++) {
+        std::pair<std::string, jobject> pair = *iter;
+        if (nullptr != pair.second) {
+            env->DeleteWeakGlobalRef(pair.second);
+            pair.second = nullptr;
+        }
+    }
+    if (!posMap.empty()) {
+        posMap.clear();
+    }
+    cacheList.clear();
+}
+
+void JStringCache::put(std::string key, jobject value) {
+//    LOGD("Remove cache jstring_cache key: %s, find: %s, max: %s", 
key.c_str(), posMap.find(key) != posMap.end() ? "TRUE" : "FALSE", 
cacheList.size() >= capacity ? "TRUE" : "FALSE");
+    if (posMap.find(key) != posMap.end()) {
+        cacheList.erase(posMap[key]);
+    } else if (cacheList.size() >= capacity) {
+        posMap.erase(cacheList.back().first);
+        cacheList.pop_back();
+    }
+    cacheList.push_front({key, value});
+    posMap[key] = cacheList.begin();
+}
+
+jstring JStringCache::GetString(JNIEnv *env, std::string key) {
+//    LOGW("JStringCache map size: %d, list size: %d", posMap.size(), 
cacheList.size());
+    if (posMap.find(key) != posMap.end()) {
+        jobject obj = posMap[key]->second;
+        if (env->IsSameObject(obj, NULL) == JNI_FALSE) {
+            // JObject is still active
+            put(key, obj);
+//            LOGE("FOUND cache jstring_cache GetString key: %s,for cache key: 
%s", key.c_str(), env->GetStringUTFChars((jstring) obj, JNI_FALSE));
+            return (jstring) posMap[key]->second;
+        }
+        if (env->IsSameObject(obj, NULL) == JNI_TRUE) {
+            // Should delete WeakGlobalRef.
+//            LOGD("delete WeakGlobalRef: key: %s", key.c_str());
+            env->DeleteWeakGlobalRef(obj);
+        }
+    }
+    const jstring jRef = env->NewStringUTF(key.c_str());
+    const jobject jGlobalRef = env->NewWeakGlobalRef(jRef);
+    put(key, jGlobalRef);
+    env->DeleteLocalRef(jRef);
+    return (jstring) jGlobalRef;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/base/string/jstring_cache.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/string/jstring_cache.h 
b/weex_core/Source/android/base/string/jstring_cache.h
new file mode 100644
index 0000000..f279a99
--- /dev/null
+++ b/weex_core/Source/android/base/string/jstring_cache.h
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+#ifndef jstring_cache_h
+#define jstring_cache_h
+
+#include <jni.h>
+#include <list>
+#include <unordered_map>
+
+class JStringCache;
+
+class JStringCache {
+
+public:
+    JStringCache(int capacity) : capacity(capacity) {}
+
+    ~JStringCache() {}
+
+public:
+    int capacity;
+    std::list<std::pair<std::string, jobject>> cacheList;
+    std::unordered_map<std::string, std::list<std::pair<std::string, 
jobject>>::iterator> posMap;
+    jstring GetString(JNIEnv *env, std::string key);
+    void clearRefCache(JNIEnv *env);
+
+private:
+    void put(std::string key, jobject value);
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp 
b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp
index be72c92..dbff771 100644
--- a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp
+++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp
@@ -24,6 +24,7 @@
 #include "bridge_impl_android.h"
 #include <core/layout/style.h>
 #include <map>
+#include <android/base/string/jstring_cache.h>
 
 static jmethodID jSetJSFrmVersionMethodId;
 static jmethodID jReportExceptionMethodId;
@@ -54,6 +55,7 @@ static jmethodID jCallUpdateAttrsMethodId;
 static jmethodID jCallLayoutMethodId;
 static jmethodID jCallCreateFinishMethodId;
 static jmethodID jCallAppendTreeCreateFinishMethodId;
+static jmethodID jCallGetMeasurementMethodId;
 
 static jmethodID jPostMessage;
 static jmethodID jDispatchMeaasge;
@@ -97,6 +99,8 @@ namespace WeexCore {
     jCallLayoutMethodId = NULL;
     jCallAppendTreeCreateFinishMethodId = NULL;
     jCallCreateFinishMethodId = NULL;
+
+    jCallGetMeasurementMethodId = NULL;
   }
 
   void static cpyCMap2JMap(std::map<std::string, std::string> *cMap, jobject 
&jMap, JNIEnv *env) {
@@ -106,10 +110,7 @@ namespace WeexCore {
     jstring jValue;
 
     for (; it != end; ++it) {
-      jKey = getStyleKeyFromCache(it->first.c_str());
-      if (jKey == nullptr) {
-        jKey = putStyleKeyToCache(it->first.c_str());
-      }
+      jKey = getKeyFromCache(env, it->first.c_str());
 
       jValue = env->NewStringUTF(it->second.c_str());
       env->CallObjectMethod(jMap, jMapPutMethodId, jKey, jValue);
@@ -122,10 +123,9 @@ namespace WeexCore {
     jstring jValue;
 
     for (int i = 0; i < cVector->size(); ++i) {
-      jKey = env->NewStringUTF((*cVector)[i].first.c_str());
+      jKey = getKeyFromCache(env, (*cVector)[i].first.c_str());
       jValue = env->NewStringUTF((*cVector)[i].second.c_str());
       env->CallObjectMethod(jMap, jMapPutMethodId, jKey, jValue);
-      env->DeleteLocalRef(jKey);
       env->DeleteLocalRef(jValue);
     }
   }
@@ -156,8 +156,6 @@ namespace WeexCore {
 
     if (jVersion != nullptr)
       env->DeleteLocalRef(jVersion);
-
-
   }
 
   void Bridge_Impl_Android::reportException(const char* pageId, const char 
*func, const char *exception_string) {
@@ -168,7 +166,7 @@ namespace WeexCore {
     JNIEnv *env = getJNIEnv();
     jstring jFunc = env->NewStringUTF(func);
     jstring jExceptionString = env->NewStringUTF(exception_string);
-    jstring jPageId = env->NewStringUTF(pageId);
+    jstring jPageId = getKeyFromCache(env, pageId);
 
     if (jReportExceptionMethodId == NULL) {
       jReportExceptionMethodId = env->GetMethodID(jBridgeClazz,
@@ -177,8 +175,6 @@ namespace WeexCore {
     }
     env->CallVoidMethod(jThis, jReportExceptionMethodId, jPageId, jFunc, 
jExceptionString);
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
     if (jFunc != nullptr)
       env->DeleteLocalRef(jFunc);
     if (jExceptionString != nullptr)
@@ -196,7 +192,7 @@ namespace WeexCore {
     JNIEnv *env = getJNIEnv();
     jbyteArray jTask = newJByteArray(env, task);
     jstring jCallback = env->NewStringUTF(callback);
-    jstring jPageId = env->NewStringUTF(pageId);
+    jstring jPageId = getKeyFromCache(env, pageId);
 
     int flag = -1;
 
@@ -214,8 +210,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callNative");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
     if (jTask != nullptr)
       env->DeleteLocalRef(jTask);
     if (jCallback != nullptr)
@@ -236,7 +230,7 @@ namespace WeexCore {
     jstring jMethod = env->NewStringUTF(method);
     jbyteArray jArgString = newJByteArray(env, argString);
     jbyteArray jOptString = newJByteArray(env, optString);
-    jstring jPageId = env->NewStringUTF(pageId);
+    jstring jPageId = getKeyFromCache(env, pageId);
 
     jobject result = nullptr;
 
@@ -250,8 +244,6 @@ namespace WeexCore {
       result = env->CallObjectMethod(jThis, jCallNativeModuleMethodId, 
jPageId, jModule, jMethod, jArgString, jOptString);
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
     if (jModule != nullptr)
       env->DeleteLocalRef(jModule);
     if (jMethod != nullptr)
@@ -276,8 +268,8 @@ namespace WeexCore {
     jstring jMethod = env->NewStringUTF(method);
     jbyteArray jArgString = newJByteArray(env, argString);
     jbyteArray jOptString = newJByteArray(env, optString);
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jMethod != nullptr) {
       if (jCallNativeComponentMethodId == NULL) {
@@ -288,10 +280,6 @@ namespace WeexCore {
       env->CallVoidMethod(jThis, jCallNativeComponentMethodId, jPageId, jRef, 
jMethod, jArgString, jOptString);
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
     if (jMethod != nullptr)
       env->DeleteLocalRef(jMethod);
     if (jArgString != nullptr)
@@ -350,7 +338,7 @@ namespace WeexCore {
     JNIEnv *env = getJNIEnv();
     jbyteArray jTask = newJByteArray(env, task);
     jstring jCallback = env->NewStringUTF(callback);
-    jstring jPageId = env->NewStringUTF(pageId);
+    jstring jPageId = getKeyFromCache(env, pageId);
 
     if (jCallUpdateFinishMethodId == NULL) {
       jCallUpdateFinishMethodId = env->GetMethodID(jBridgeClazz,
@@ -364,8 +352,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callUpdateFinish");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
     if (jTask != nullptr)
       env->DeleteLocalRef(jTask);
     if (jCallback != nullptr)
@@ -384,7 +370,7 @@ namespace WeexCore {
     JNIEnv *env = getJNIEnv();
     jbyteArray jTask = newJByteArray(env, task);
     jstring jCallback = env->NewStringUTF(callback);
-    jstring jPageId = env->NewStringUTF(pageId);
+    jstring jPageId = getKeyFromCache(env, pageId);
 
     if (jCallRefreshFinishMethodId == NULL) {
       jCallRefreshFinishMethodId = env->GetMethodID(jBridgeClazz,
@@ -397,8 +383,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callNative");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
     if (jTask != nullptr)
       env->DeleteLocalRef(jTask);
     if (jCallback != nullptr)
@@ -420,8 +404,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jMapConstructorMethodId == NULL)
       jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V");
@@ -445,27 +430,25 @@ namespace WeexCore {
     float c_margins[4];
     float c_paddings[4];
     float c_borders[4];
-    jfloatArray jMargins = env->NewFloatArray(4);
-    jfloatArray jPaddings = env->NewFloatArray(4);
-    jfloatArray jBorders = env->NewFloatArray(4);
 
     c_margins[0] = margins.getMargin(kMarginTop);
     c_margins[1] = margins.getMargin(kMarginBottom);
     c_margins[2] = margins.getMargin(kMarginLeft);
     c_margins[3] = margins.getMargin(kMarginRight);
-    env->SetFloatArrayRegion(jMargins, 0, 4, c_margins);
 
     c_paddings[0] = paddings.getPadding(kPaddingTop);
     c_paddings[1] = paddings.getPadding(kPaddingBottom);
     c_paddings[2] = paddings.getPadding(kPaddingLeft);
     c_paddings[3] = paddings.getPadding(kPaddingRight);
-    env->SetFloatArrayRegion(jPaddings, 0, 4, c_paddings);
 
     c_borders[0] = borders.getBorderWidth(kBorderWidthTop);
     c_borders[1] = borders.getBorderWidth(kBorderWidthBottom);
     c_borders[2] = borders.getBorderWidth(kBorderWidthLeft);
     c_borders[3] = borders.getBorderWidth(kBorderWidthRight);
-    env->SetFloatArrayRegion(jBorders, 0, 4, c_borders);
+
+    jfloatArray jMargins = c2jFloatArray(env, c_margins);
+    jfloatArray jPaddings = c2jFloatArray(env, c_paddings);
+    jfloatArray jBorders = c2jFloatArray(env, c_borders);
 
     if (jCallCreateBodyMethodId == NULL)
       jCallCreateBodyMethodId = env->GetMethodID(jBridgeClazz,
@@ -487,10 +470,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callCreateBody");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
     env->DeleteLocalRef(jStyles);
     env->DeleteLocalRef(jAttributes);
     env->DeleteLocalRef(jEvents);
@@ -512,11 +491,10 @@ namespace WeexCore {
                                           const WXCorePadding &paddings,
                                           const WXCoreBorderWidth &borders,
                                           bool willLayout) {
-
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
-    jstring jParentRef = env->NewStringUTF(parentRef);
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
+    jstring jParentRef = getKeyFromCache(env, parentRef);
 
     if (jMapConstructorMethodId == NULL)
       jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V");
@@ -540,27 +518,25 @@ namespace WeexCore {
     float c_margins[4];
     float c_paddings[4];
     float c_borders[4];
-    jfloatArray jMargins = env->NewFloatArray(4);
-    jfloatArray jPaddings = env->NewFloatArray(4);
-    jfloatArray jBorders = env->NewFloatArray(4);
 
     c_margins[0] = margins.getMargin(kMarginTop);
     c_margins[1] = margins.getMargin(kMarginBottom);
     c_margins[2] = margins.getMargin(kMarginLeft);
     c_margins[3] = margins.getMargin(kMarginRight);
-    env->SetFloatArrayRegion(jMargins, 0, 4, c_margins);
 
     c_paddings[0] = paddings.getPadding(kPaddingTop);
     c_paddings[1] = paddings.getPadding(kPaddingBottom);
     c_paddings[2] = paddings.getPadding(kPaddingLeft);
     c_paddings[3] = paddings.getPadding(kPaddingRight);
-    env->SetFloatArrayRegion(jPaddings, 0, 4, c_paddings);
 
     c_borders[0] = borders.getBorderWidth(kBorderWidthTop);
     c_borders[1] = borders.getBorderWidth(kBorderWidthBottom);
     c_borders[2] = borders.getBorderWidth(kBorderWidthLeft);
     c_borders[3] = borders.getBorderWidth(kBorderWidthRight);
-    env->SetFloatArrayRegion(jBorders, 0, 4, c_borders);
+
+    jfloatArray jMargins = c2jFloatArray(env, c_margins);
+    jfloatArray jPaddings = c2jFloatArray(env, c_paddings);
+    jfloatArray jBorders = c2jFloatArray(env, c_borders);
 
     if (jCallAddElementMethodId == NULL)
       jCallAddElementMethodId = env->GetMethodID(jBridgeClazz,
@@ -580,12 +556,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callAddElement");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-    if (jParentRef != nullptr)
-      env->DeleteLocalRef(jParentRef);
     env->DeleteLocalRef(jStyles);
     env->DeleteLocalRef(jAttributes);
     env->DeleteLocalRef(jEvents);
@@ -602,8 +572,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jCallRemoveElementMethodId == NULL) {
       jCallRemoveElementMethodId = env->GetMethodID(jBridgeClazz,
@@ -616,11 +587,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callRemoveElement");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
     return 0;
@@ -632,9 +598,10 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
-    jstring jParentRef = env->NewStringUTF(parentRef);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
+    jstring jParentRef = getKeyFromCache(env, parentRef);
 
     if (jCallMoveElementMethodId == NULL) {
       jCallMoveElementMethodId = env->GetMethodID(jBridgeClazz,
@@ -647,13 +614,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callRemoveElement");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-    if (jParentRef != nullptr)
-      env->DeleteLocalRef(jParentRef);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
     return 0;
@@ -665,8 +625,8 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jCallAddEventMethodId == NULL) {
       jCallAddEventMethodId = env->GetMethodID(jBridgeClazz,
@@ -680,14 +640,9 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callAddEvent");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-    env->DeleteLocalRef(jEventId);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
+    env->DeleteLocalRef(jEventId);
     return flag;
   }
 
@@ -697,8 +652,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jCallRemoveEventMethodId == NULL) {
       jCallRemoveEventMethodId = env->GetMethodID(jBridgeClazz,
@@ -712,14 +668,9 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callRemoveElement");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-    env->DeleteLocalRef(jEventId);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
+    env->DeleteLocalRef(jEventId);
     return flag;
   }
 
@@ -732,8 +683,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jMapConstructorMethodId == NULL)
       jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V");
@@ -774,10 +726,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callUpdateStyle");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
     env->DeleteLocalRef(jStyles);
     env->DeleteLocalRef(jMargins);
     env->DeleteLocalRef(jPaddings);
@@ -794,8 +742,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jMapConstructorMethodId == NULL)
       jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V");
@@ -822,10 +771,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callUpdateStyle");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
     env->DeleteLocalRef(jAttrs);
 
     if (page != nullptr)
@@ -841,8 +786,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jCallLayoutMethodId == NULL)
       jCallLayoutMethodId = env->GetMethodID(jBridgeClazz,
@@ -857,11 +803,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callLayout");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
     return flag;
@@ -873,7 +814,8 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
 
     if (jCallCreateFinishMethodId == NULL)
       jCallCreateFinishMethodId = env->GetMethodID(jBridgeClazz,
@@ -886,9 +828,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callCreateFinish");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
     return flag;
@@ -900,8 +839,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jCallAppendTreeCreateFinishMethodId == NULL)
       jCallAppendTreeCreateFinishMethodId = env->GetMethodID(jBridgeClazz,
@@ -915,11 +855,6 @@ namespace WeexCore {
       LOGE("instance destroy JFM must stop callAppendTreeCreateFinish");
     }
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
-
     if (page != nullptr)
       page->CallBridgeTime(getCurrentTime() - startTime);
     return flag;
@@ -931,8 +866,9 @@ namespace WeexCore {
     long long startTime = getCurrentTime();
 
     JNIEnv *env = getJNIEnv();
-    jstring jPageId = env->NewStringUTF(pageId);
-    jstring jRef = env->NewStringUTF(ref);
+
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
 
     if (jMapConstructorMethodId == NULL)
       jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V");
@@ -954,10 +890,6 @@ namespace WeexCore {
     int flag = 0;
     flag = env->CallIntMethod(jThis, jCallHasTransitionProsMethodId, jPageId, 
jRef, jStyles);
 
-    if (jPageId != nullptr)
-      env->DeleteLocalRef(jPageId);
-    if (jRef != nullptr)
-      env->DeleteLocalRef(jRef);
     env->DeleteLocalRef(jStyles);
 
     if (page != nullptr)
@@ -985,4 +917,16 @@ namespace WeexCore {
     }
     env->CallVoidMethod(jWMThis, jDispatchMeaasge, jClientId, jVmId, jData, 
jCallback);
   }
+
+  jobject Bridge_Impl_Android::getMeasureFunc(const char* pageId, const char* 
ref) {
+    JNIEnv *env = getJNIEnv();
+    jstring jPageId = getKeyFromCache(env, pageId);
+    jstring jRef = getKeyFromCache(env, ref);
+    if (jCallGetMeasurementMethodId == NULL) {
+      jCallGetMeasurementMethodId = env->GetMethodID(jBridgeClazz,
+                                                     "getMeasurementFunc",
+                                                     
"(Ljava/lang/String;Ljava/lang/String;)Lcom/taobao/weex/layout/ContentBoxMeasurement;");
+    }
+    return env->CallObjectMethod(jThis, jCallGetMeasurementMethodId, jPageId, 
jRef);
+  }
 } //end WeexCore
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/bridge/impl/bridge_impl_android.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.h 
b/weex_core/Source/android/bridge/impl/bridge_impl_android.h
index fee8942..50c8ba0 100644
--- a/weex_core/Source/android/bridge/impl/bridge_impl_android.h
+++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.h
@@ -132,6 +132,8 @@ namespace WeexCore {
     void handlePostMessage(jstring jVmId, jbyteArray jData);
 
     void handleDispatchMessage(jstring jClientId, jstring jVmId, jbyteArray 
jData, jstring jCallback);
+
+    jobject getMeasureFunc(const char* pageId, const char* ref);
   };
 } //end WeexCore
 #endif //BridgeAndroid_h
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp 
b/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp
index ef79558..039174e 100644
--- a/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp
+++ b/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp
@@ -39,7 +39,8 @@ jmethodID jDoubleValueMethodId;
 jobject jThis;
 jobject jWMThis;
 std::map<std::string, jobject> componentTypeCache;
-std::map<std::string, jobject> styleKeyCache;
+
+JStringCache refCache(2048);
 
 static JavaVM *sVm = NULL;
 
@@ -69,22 +70,24 @@ jstring putComponentTypeToCache(const std::string type) {
   return (jstring) jGlobalType;
 }
 
-jstring getStyleKeyFromCache(const std::string key) {
-  std::map<std::string, jobject>::const_iterator iter = 
styleKeyCache.find(key);
-  if (iter != styleKeyCache.end()) {
-    return (jstring)(iter->second);
-  } else {
-    return nullptr;
-  }
+jstring getKeyFromCache(JNIEnv *env, const char *key) {
+  return refCache.GetString(env, key);
 }
 
-jstring putStyleKeyToCache(const std::string key) {
-  JNIEnv *env = getJNIEnv();
-  jstring jKey = env->NewStringUTF(key.c_str());
-  jobject jGlobalKey = env->NewGlobalRef(jKey);
-  styleKeyCache.insert(std::pair<std::string, jobject>(key, jGlobalKey));
-  env->DeleteLocalRef(jKey);
-  return (jstring) jGlobalKey;
+jfloatArray c2jFloatArray(JNIEnv *env, const float c_array[]) {
+  if (nullptr == c_array) {
+    return nullptr;
+  }
+  if (0 == c_array[0]
+      && 0 == c_array[1]
+      && 0 == c_array[2]
+      && 0 == c_array[3]) {
+    // Default value;
+    return nullptr;
+  }
+  jfloatArray jArray = env->NewFloatArray(4);
+  env->SetFloatArrayRegion(jArray, 0, 4, c_array);
+  return jArray;
 }
 
 static jint InitFrameworkEnv(JNIEnv *env, jobject jcaller,
@@ -100,27 +103,11 @@ static jint InitFrameworkEnv(JNIEnv *env, jobject jcaller,
   return WeexProxy::doInitFramework(env, jThis, framework, params, cacheDir, 
pieSupport);
 }
 
-static void BindMeasurementToWXCore(JNIEnv *env, jobject jcaller, jstring 
instanceId, jstring ref, jobject contentBoxMeasurement) {
-  if (contentBoxMeasurement == nullptr)
-    return;
-
-  RenderPage *page = 
RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId));
-  if (page == nullptr)
-    return;
-
-  RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref));
-  if (render == nullptr)
-    return;
-
-  render->BindMeasureFuncImplAndroid(contentBoxMeasurement);
-}
-
 static void BindMeasurementToRenderObject(JNIEnv* env, jobject jcaller,
-                                          jlong ptr,
-                                          jobject contentBoxMeasurement){
+                                          jlong ptr){
   RenderObject *render =  convert_long_to_render_object(ptr);
   if(render){
-    render->BindMeasureFuncImplAndroid(contentBoxMeasurement);
+      render->BindMeasureFuncImplAndroid();
   }
 }
 
@@ -194,10 +181,10 @@ static jboolean NotifyLayout(JNIEnv* env, jobject 
jcaller, jstring instanceId) {
   RenderPage *page = 
RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId));
   if (page != nullptr) {
 
-#if RENDER_LOG
-    LOGD("[JNI] NotifyLayout >>>> pageId: %s, needForceLayout: %s, dirty: %s", 
jString2StrFast(env, instanceId).c_str(),
-         page->needLayout.load() ? "true" : "false", page->isDirty() ? "true" 
: "false");
-#endif
+//#if RENDER_LOG
+//    LOGD("[JNI] NotifyLayout >>>> pageId: %s, needForceLayout: %s, dirty: 
%s", jString2StrFast(env, instanceId).c_str(),
+//         page->needLayout.load() ? "true" : "false", page->isDirty() ? 
"true" : "false");
+//#endif
 
     if (!page->needLayout.load()) {
       page->needLayout.store(true);
@@ -568,13 +555,7 @@ jint OnLoad(JavaVM *vm, void *reserved) {
     }
     componentTypeCache.clear();
 
-    for (auto iter = styleKeyCache.begin(); iter != styleKeyCache.end(); 
iter++) {
-      if (iter->second != nullptr) {
-        env->DeleteGlobalRef(iter->second);
-        iter->second = nullptr;
-      }
-    }
-    styleKeyCache.clear();
+    refCache.clearRefCache(env);
 
     if (jThis)
       env->DeleteGlobalRef(jThis);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/bridge/impl/weexcore_impl_android.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/bridge/impl/weexcore_impl_android.h 
b/weex_core/Source/android/bridge/impl/weexcore_impl_android.h
index b43891f..b88256d 100644
--- a/weex_core/Source/android/bridge/impl/weexcore_impl_android.h
+++ b/weex_core/Source/android/bridge/impl/weexcore_impl_android.h
@@ -23,6 +23,7 @@
 #include <android/base/string/scoped_jstring.h>
 #include <android/base/string/scoped_jstring_utf8.h>
 #include <android/jsengine/multiprocess/WeexJSConnection.h>
+#include <android/base/string/jstring_cache.h>
 #include <jni.h>
 #include <string>
 #include <unistd.h>
@@ -41,8 +42,8 @@ extern jclass jWMBridgeClazz;
 extern JNIEnv *getJNIEnv();
 extern jstring getComponentTypeFromCache(const std::string type);
 extern jstring putComponentTypeToCache(const std::string type);
-extern jstring getStyleKeyFromCache(const std::string key);
-extern jstring putStyleKeyToCache(const std::string key);
+extern jstring getKeyFromCache(JNIEnv *env, const char *key);
+extern jfloatArray c2jFloatArray(JNIEnv *env, const float c_array[]);
 
 namespace WeexCore {
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h 
b/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h
index e89ad36..424b1f2 100644
--- a/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h
+++ b/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h
@@ -68,14 +68,8 @@ static jstring ExecJSOnInstance(JNIEnv* env, jobject jcaller,
 static void TakeHeapSnapshot(JNIEnv* env, jobject jcaller,
     jstring filename);
 
-static void BindMeasurementToWXCore(JNIEnv* env, jobject jcaller,
-    jstring instanceId,
-    jstring ref,
-    jobject contentBoxMeasurement);
-
 static void BindMeasurementToRenderObject(JNIEnv* env, jobject jcaller,
-    jlong ptr,
-    jobject contentBoxMeasurement);
+    jlong ptr);
 
 static void SetRenderContainerWrapContent(JNIEnv* env, jobject jcaller,
     jboolean wrap,
@@ -215,17 +209,9 @@ static const JNINativeMethod kMethodsWXBridge[] = {
 "Ljava/lang/String;"
 ")"
 "V", reinterpret_cast<void*>(TakeHeapSnapshot) },
-    { "nativeBindMeasurementToWXCore",
-"("
-"Ljava/lang/String;"
-"Ljava/lang/String;"
-"Lcom/taobao/weex/layout/ContentBoxMeasurement;"
-")"
-"V", reinterpret_cast<void*>(BindMeasurementToWXCore) },
     { "nativeBindMeasurementToRenderObject",
 "("
 "J"
-"Lcom/taobao/weex/layout/ContentBoxMeasurement;"
 ")"
 "V", reinterpret_cast<void*>(BindMeasurementToRenderObject) },
     { "nativeSetRenderContainerWrapContent",

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/core/layout/layout.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/layout/layout.h 
b/weex_core/Source/core/layout/layout.h
index 4233896..7bd32dc 100644
--- a/weex_core/Source/core/layout/layout.h
+++ b/weex_core/Source/core/layout/layout.h
@@ -235,15 +235,15 @@ namespace WeexCore {
       markDirty();
     }
 
-    inline WXCoreMeasureFunc getMeasureFunc() const {
-      return measureFunc;
+    inline bool haveMeasureFunc() const {
+      return nullptr != measureFunc;
     }
 
-    inline bool haveMeasureFunc() const {
-      return measureFunc != nullptr;
+    inline WXCoreMeasureFunc getMeasureFunc() const {
+      return measureFunc;
     }
 
-    /** ================================ context 
=================================== **/
+      /** ================================ context 
=================================== **/
 
 
     inline void *getContext() const {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/core/render/manager/render_manager.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/manager/render_manager.cpp 
b/weex_core/Source/core/render/manager/render_manager.cpp
index d3e9b11..0429233 100644
--- a/weex_core/Source/core/render/manager/render_manager.cpp
+++ b/weex_core/Source/core/render/manager/render_manager.cpp
@@ -198,7 +198,7 @@ namespace WeexCore {
 #if RENDER_LOG
     LOGD("[RenderManager] ClosePage >>>> pageId: %s", pageId.c_str());
 #endif
-
+    page->OnRenderPageClose();
     mPages.erase(pageId);
     delete page;
     page = nullptr;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/core/render/node/render_object.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_object.cpp 
b/weex_core/Source/core/render/node/render_object.cpp
index 1ce1a4b..683fa62 100644
--- a/weex_core/Source/core/render/node/render_object.cpp
+++ b/weex_core/Source/core/render/node/render_object.cpp
@@ -31,7 +31,6 @@ namespace WeexCore {
     mStyles = new StylesMap();
     mAttributes = new AttributesMap();
     mEvents = new EventsSet();
-    mMeasureFunc_Impl_Android = nullptr;
     mIsRootRender = false;
   }
 
@@ -54,11 +53,6 @@ namespace WeexCore {
       mEvents = nullptr;
     }
 
-    if (mMeasureFunc_Impl_Android != nullptr) {
-      env->DeleteGlobalRef(mMeasureFunc_Impl_Android);
-      mMeasureFunc_Impl_Android = nullptr;
-    }
-
     for(auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
       RenderObject* child = static_cast<RenderObject*>(*it);
       if (child != nullptr) {
@@ -101,15 +95,17 @@ namespace WeexCore {
 
   WXCoreSize measureFunc_Impl(WXCoreLayoutNode *node, float width, MeasureMode 
widthMeasureMode,
                               float height, MeasureMode heightMeasureMode) {
-    JNIEnv *env = getJNIEnv();
     WXCoreSize size;
     size.height = 0;
     size.width = 0;
 
     jobject measureFunc = ((RenderObject *) node)->GetMeasureFuncImplAndroid();
 
-    if (node == nullptr || measureFunc == nullptr)
+    if (node == nullptr || measureFunc == nullptr) {
       return size;
+    }
+
+    JNIEnv *env = getJNIEnv();
 
     int widthMode = Unspecified(env);
     int heightMode = Unspecified(env);
@@ -123,35 +119,37 @@ namespace WeexCore {
     size.width = GetLayoutWidth(env, measureFunc);
     size.height = GetLayoutHeight(env, measureFunc);
 
+    env->DeleteLocalRef(measureFunc);
+
     return size;
   }
 
-  bool RenderObject::BindMeasureFuncImplAndroid(jobject 
measureFunc_impl_android) {
-    if (measureFunc_impl_android == nullptr)
-      return false;
-    this->mMeasureFunc_Impl_Android = 
getJNIEnv()->NewGlobalRef(measureFunc_impl_android);
-    setMeasureFunc(measureFunc_Impl);
-    return true;
+  void RenderObject::BindMeasureFuncImplAndroid() {
+     setMeasureFunc(measureFunc_Impl);
   }
 
-  bool RenderObject::BindMeasureFuncImplIOS(WXCoreMeasureFunc 
measureFunc_impl_ios) {
-    if (measureFunc_impl_ios == nullptr)
-      return false;
+  void RenderObject::BindMeasureFuncImplIOS(WXCoreMeasureFunc 
measureFunc_impl_ios) {
     setMeasureFunc(measureFunc_impl_ios);
-    return true;
   }
 
   void RenderObject::onLayoutBefore() {
-    if (this->GetMeasureFuncImplAndroid() == nullptr)
-      return;
+    jobject measureFunc = this->GetMeasureFuncImplAndroid();
+    if(nullptr == measureFunc) {
+       return;
+    }
+
     JNIEnv *env = getJNIEnv();
-    LayoutBeforeImplAndroid(env, this->GetMeasureFuncImplAndroid());
+    LayoutBeforeImplAndroid(env, measureFunc);
+    env->DeleteLocalRef(measureFunc);
   }
 
   void RenderObject::onLayoutAfter(float width, float height) {
-    if (this->GetMeasureFuncImplAndroid() == nullptr)
-      return;
+    jobject measureFunc = this->GetMeasureFuncImplAndroid();
+    if(nullptr == measureFunc) {
+       return;
+    }
     JNIEnv *env = getJNIEnv();
-    LayoutAfterImplAndroid(env, this->GetMeasureFuncImplAndroid(), width, 
height);
+    LayoutAfterImplAndroid(env, measureFunc, width, height);
+    env->DeleteLocalRef(measureFunc);
   }
 } //end WeexCore

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/core/render/node/render_object.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_object.h 
b/weex_core/Source/core/render/node/render_object.h
index 15d3f8c..7c45485 100644
--- a/weex_core/Source/core/render/node/render_object.h
+++ b/weex_core/Source/core/render/node/render_object.h
@@ -32,6 +32,7 @@
 #include <core/render/page/render_page.h>
 #include <core/css/constants_value.h>
 #include <android/base/log_utils.h>
+#include <android/bridge/impl/bridge_impl_android.h>
 #include <functional>
 
 
@@ -143,9 +144,9 @@ namespace WeexCore {
 
     ~RenderObject();
 
-    bool BindMeasureFuncImplAndroid(jobject measureFunc_impl_android);
+    void BindMeasureFuncImplAndroid();
 
-    bool BindMeasureFuncImplIOS(WXCoreMeasureFunc measureFunc_impl_ios);
+    void BindMeasureFuncImplIOS(WXCoreMeasureFunc measureFunc_impl_ios);
 
     void onLayoutBefore();
 
@@ -281,7 +282,10 @@ namespace WeexCore {
     void ApplyDefaultAttr();
 
     inline jobject GetMeasureFuncImplAndroid() {
-      return mMeasureFunc_Impl_Android;
+      if (!haveMeasureFunc()) {
+        return nullptr;
+      }
+      return 
Bridge_Impl_Android::getInstance()->getMeasureFunc(PageId().c_str(), 
Ref().c_str());
     }
 
     inline RenderObject *GetChild(const Index &index) {
@@ -447,7 +451,6 @@ namespace WeexCore {
     StylesMap *mStyles;
     AttributesMap *mAttributes;
     EventsSet *mEvents;
-    jobject mMeasureFunc_Impl_Android;
     float mViewPortWidth = -1;
     bool mIsRootRender;
   };

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/641e3826/weex_core/Source/core/render/page/render_page.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/page/render_page.cpp 
b/weex_core/Source/core/render/page/render_page.cpp
index f0c6a05..cb10636 100644
--- a/weex_core/Source/core/render/page/render_page.cpp
+++ b/weex_core/Source/core/render/page/render_page.cpp
@@ -606,7 +606,6 @@ namespace WeexCore {
   }
 
   void RenderPage::OnRenderPageInit() {
-
   }
 
   void RenderPage::OnRenderProcessStart() {
@@ -622,6 +621,5 @@ namespace WeexCore {
   }
 
   void RenderPage::OnRenderPageClose() {
-
   }
 } //namespace WeexCore

Reply via email to