You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by to...@apache.org on 2018/03/27 08:45:58 UTC

[04/11] incubator-weex git commit: * [WEEX-240] [android] feature update for weexsandbox and size off so 1. every page will has a runtime context independent of other page 2. At the beginning of js, will use // {"framework" : "Rax"} or // {"f

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/build.gradle
----------------------------------------------------------------------
diff --git a/android/sdk/build.gradle b/android/sdk/build.gradle
index 728e1c6..ecb40c2 100755
--- a/android/sdk/build.gradle
+++ b/android/sdk/build.gradle
@@ -60,6 +60,19 @@ android {
     def jsfmVersion = m[0][1]
     println jsfmVersion
 
+    copy {
+        from '../../pre-build'
+        into new File(projectDir,"assets")
+        include 'weex-main-jsfm.js'
+        rename('weex-main-jsfm.js','weex-main-jsfm.js')
+    }
+
+    copy {
+        from '../../pre-build'
+        into new File(projectDir,"assets")
+        include 'weex-rax-api.js'
+    }
+
     if(project.hasProperty('asfRelease')){
         //download so file if not exist, when compile in source release
         download{

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/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/640c53f1/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 3c386f1..f45aee4
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/640c53f1/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 bdedcc5..51bbd4d
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/640c53f1/android/sdk/libs/armeabi/libweexjst.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/armeabi/libweexjst.so b/android/sdk/libs/armeabi/libweexjst.so
index bca44ad..099256c 100755
Binary files a/android/sdk/libs/armeabi/libweexjst.so and b/android/sdk/libs/armeabi/libweexjst.so differ

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/libs/x86/libweexjsc.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/x86/libweexjsc.so b/android/sdk/libs/x86/libweexjsc.so
index 3e2bf9a..b86a821 100755
Binary files a/android/sdk/libs/x86/libweexjsc.so and b/android/sdk/libs/x86/libweexjsc.so differ

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/libs/x86/libweexjss.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/x86/libweexjss.so b/android/sdk/libs/x86/libweexjss.so
index 13c858f..fc8e5f6 100755
Binary files a/android/sdk/libs/x86/libweexjss.so and b/android/sdk/libs/x86/libweexjss.so differ

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/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 e6084d9..96ca990 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
@@ -119,6 +119,9 @@ public class WXEnvironment {
     configs.put(WXConfig.weexVersion, String.valueOf(WXSDK_VERSION));
     configs.put(WXConfig.logLevel,sLogLevel.getName());
     try {
+      if (isApkDebugable()) {
+        options.put(WXConfig.debugMode, "true");
+      }
       options.put(WXConfig.scale, Float.toString(sApplication.getResources().getDisplayMetrics().density));
     }catch (NullPointerException e){
       //There is little chance of NullPointerException as sApplication may be null.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java b/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
index 618502d..cbcac83 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
@@ -393,14 +393,19 @@ public class WXSDKEngine {
 
   public static boolean registerComponent(IFComponentHolder holder, boolean appendTree, String ... names) throws WXException {
     boolean result =  true;
-    for(String name:names) {
-      Map<String, Object> componentInfo = new HashMap<>();
-      if (appendTree) {
-        componentInfo.put("append", "tree");
+    try {
+      for (String name : names) {
+        Map<String, Object> componentInfo = new HashMap<>();
+        if (appendTree) {
+          componentInfo.put("append", "tree");
+        }
+        result = result && WXComponentRegistry.registerComponent(name, holder, componentInfo);
       }
-      result  = result && WXComponentRegistry.registerComponent(name, holder, componentInfo);
+      return result;
+    } catch (Throwable e) {
+      e.printStackTrace();
+      return result;
     }
-    return result;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/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 8e6534e..40cdf21 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -175,6 +175,13 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
   private ComponentObserver mComponentObserver;
   private boolean mIsCommitedDomAtionExp = false;
 
+  /**
+   * set open SandBox
+   * @param flag
+   */
+  public void setUseSandBox(boolean flag) {
+    WXBridgeManager.getInstance().setSandBoxContext(flag);
+  }
   public PriorityQueue<WXEmbed> hiddenEmbeds;
 
   private int maxHiddenEmbedsNum = -1; //max hidden embed num, -1 standard for ulimit

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/src/main/java/com/taobao/weex/bridge/ModuleFactoryImpl.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/ModuleFactoryImpl.java b/android/sdk/src/main/java/com/taobao/weex/bridge/ModuleFactoryImpl.java
new file mode 100644
index 0000000..fe0e00a
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/ModuleFactoryImpl.java
@@ -0,0 +1,38 @@
+/**
+ * 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.bridge;
+
+/**
+ * Created by shiwentao on 2018/3/13.
+ */
+
+public class ModuleFactoryImpl {
+    public ModuleFactory mFactory = null;
+    public boolean hasRigster = false;
+
+    public ModuleFactoryImpl(ModuleFactory factory) {
+        mFactory = factory;
+    }
+
+    public ModuleFactoryImpl(ModuleFactory factory, boolean rigister) {
+        mFactory = factory;
+        hasRigster = rigister;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/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 ef30168..20b37e1 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
@@ -64,9 +64,28 @@ class WXBridge implements IWXBridge {
    */
   public native int execJS(String instanceId, String namespace, String function, WXJSObject[] args);
 
+ /**
+   * nativeCreateInstanceContext
+   * @param instanceId
+   * @param name
+   * @param function
+   * @param args
+   * @return
+   */
+  public native int createInstanceContext(String instanceId, String name, String function, WXJSObject[] args);
 
 
   /**
+   * nativeDestoryInstance
+   * @param instanceId
+   * @param name
+   * @param function
+   * @param args
+   * @return
+   */
+  public native int destoryInstance(String instanceId, String name, String function, WXJSObject[] args);
+
+  /**
    * Execute JavaScript function
    *
    * @param instanceId
@@ -85,6 +104,15 @@ class WXBridge implements IWXBridge {
    */
   public native int execJSService(String javascript);
 
+
+  /**
+   * execJSOnInstance
+   * @param instanceId id
+   * @param script js
+   * @param type tag: sync | async | global | instance
+   * @return value
+   */
+  public native String execJSOnInstance(String instanceId, String script, int type);
   /**
    * Take v8's heap snapshot
    * @param filename the name of the file to be written.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/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 0e2c722..f45150f 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
@@ -19,6 +19,7 @@
 package com.taobao.weex.bridge;
 
 import android.content.Context;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Handler.Callback;
@@ -56,6 +57,7 @@ import com.taobao.weex.dom.action.Action;
 import com.taobao.weex.dom.action.Actions;
 import com.taobao.weex.dom.action.TraceableAction;
 import com.taobao.weex.tracing.WXTracing;
+import com.taobao.weex.ui.WXComponentRegistry;
 import com.taobao.weex.utils.WXExceptionUtils;
 import com.taobao.weex.utils.WXFileUtils;
 import com.taobao.weex.utils.WXJsonUtils;
@@ -77,12 +79,15 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Stack;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import static com.taobao.weex.bridge.WXModuleManager.getDomModule;
 import static com.taobao.weex.bridge.WXModuleManager.createDomModule;
 
@@ -140,6 +145,8 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   public static final String INITLOGFILE = "/jsserver_start.log";
   private static final String NON_CALLBACK = "-1";
   private static final String UNDEFINED = "undefined";
+
+  private static final String BUNDLE_TYPE = "bundleType";
   private static final int INIT_FRAMEWORK_OK = 1;
   private static final int CRASHREINIT = 50;
   static volatile WXBridgeManager mBridgeManager;
@@ -147,6 +154,18 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   private volatile static int reInitCount = 1;
   private static String crashUrl = null;
   private static long lastCrashTime = 0;
+  private static String mRaxApi = null;
+
+  // add for clound setting, default value is true
+  // can use it to control weex sandbox
+  // if true will open weex sandbox for multi context
+  private volatile static boolean isSandBoxContext = true;
+
+  private enum BundType {
+    Vue,
+    Rax,
+    Others
+  };
 
   /**
    * Whether JS Framework(main.js) has been initialized.
@@ -200,6 +219,46 @@ public class WXBridgeManager implements Callback, BactchExecutor {
     return mBridgeManager;
   }
 
+  public void setSandBoxContext(final boolean flag) {
+    if (flag != isSandBoxContext) {
+      isSandBoxContext = flag;
+      // use diff context reinit jsf
+      if (isJSThread()) {
+
+        setJSFrameworkInit(false);
+        WXModuleManager.resetAllModuleState();
+        String jsf = "";
+        if (!isSandBoxContext) {
+          jsf = WXFileUtils.loadAsset("main.js", WXEnvironment.getApplication());
+        } else {
+          jsf = WXFileUtils.loadAsset("weex-main-jsfm.js", WXEnvironment.getApplication());
+        }
+        initFramework(jsf);
+        WXServiceManager.reload();
+        WXModuleManager.reload();
+        WXComponentRegistry.reload();
+      } else {
+        post(new Runnable() {
+          @Override
+          public void run() {
+            setJSFrameworkInit(false);
+            WXModuleManager.resetAllModuleState();
+            String jsf = "";
+            if (!isSandBoxContext) {
+              jsf = WXFileUtils.loadAsset("main.js", WXEnvironment.getApplication());
+            } else {
+              jsf = WXFileUtils.loadAsset("weex-main-jsfm.js", WXEnvironment.getApplication());
+            }
+            initFramework(jsf);
+            WXServiceManager.reload();
+            WXModuleManager.reload();
+            WXComponentRegistry.reload();
+          }
+        }, null);
+      }
+    }
+  }
+
   // setJSFrameworkInit and isJSFrameworkInit may use on diff thread
   // use volatile
   private boolean isJSFrameworkInit() {
@@ -291,6 +350,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
    */
   public void restart() {
     setJSFrameworkInit(false);
+    WXModuleManager.resetAllModuleState();
     initWXBridge(WXEnvironment.sRemoteDebugMode);
   }
 
@@ -1018,6 +1078,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
       reInitCount++;
       // reinit frame work
       setJSFrameworkInit(false);
+      WXModuleManager.resetAllModuleState();
       initScriptsFramework("");
 
       if (mDestroyedInstanceId != null && mDestroyedInstanceId.contains(instanceId)) {
@@ -1113,6 +1174,24 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   }
 
 
+  public String syncExecJsOnInstanceWithResult(final String instanceId, final String js, final int type) {
+    final CountDownLatch waitLatch = new CountDownLatch(1);
+    EventResult callback = new EventResult(){
+      @Override
+      public void onCallback(Object result) {
+        super.onCallback(result);
+        waitLatch.countDown();
+      }
+    };
+    try{
+      execJSOnInstance(callback, instanceId, js, type);
+      waitLatch.await(100, TimeUnit.MILLISECONDS);
+      return  callback.getResult().toString();
+    }catch (Exception e){
+      WXLogUtils.e("syncCallExecJsOnInstance", e);
+      return  "";
+    }
+  }
 
   /**
    * ref, type, data, domChanges
@@ -1575,6 +1654,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   private void invokeCreateInstance(@NonNull WXSDKInstance instance, String template,
                                     Map<String, Object> options, String data) {
 
+    // add for sandbox, will delete on sandbox ok
     initFramework("");
 
     if (mMock) {
@@ -1589,7 +1669,45 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         WXLogUtils.e(err);
         return;
       }
+
+      WXModuleManager.registerWhenCreateInstance();
+
       try {
+        BundType type = BundType.Others;
+        try {
+          long start = System.currentTimeMillis();
+          type = getBundleType(instance.getBundleUrl(), template);
+
+          if (WXEnvironment.isOpenDebugLog()) {
+            long end = System.currentTimeMillis();
+            WXLogUtils.e("end getBundleType type:" + type.toString() + " time:" + (end - start));
+          }
+        } catch (Throwable e) {
+          e.printStackTrace();
+        }
+        try {
+          if (options == null) {
+            options = new HashMap<>();
+          }
+          // on file there is { "framework": "Vue" } or others
+          if (options.get(BUNDLE_TYPE) == null) {
+            // may vue or Rax
+            if (type == BundType.Vue) {
+              options.put(BUNDLE_TYPE, "Vue");
+            } else if (type == BundType.Rax) {
+              options.put(BUNDLE_TYPE, "Rax");
+            } else {
+              options.put(BUNDLE_TYPE, "Others");
+            }
+          }
+          if (options.get("env") == null) {
+            options.put("env", mInitParams);
+          }
+        } catch (Throwable e) {
+          e.printStackTrace();
+        }
+
+
         if (WXEnvironment.isOpenDebugLog()) {
           WXLogUtils.d("createInstance >>>> instanceId:" + instance.getInstanceId()
               + ", options:"
@@ -1603,12 +1721,37 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         WXJSObject optionsObj = new WXJSObject(WXJSObject.JSON,
             options == null ? "{}"
                 : WXJsonUtils.fromObjectToJSONString(options));
+        optionsObj = optionObjConvert(isSandBoxContext, type, optionsObj);
         WXJSObject dataObj = new WXJSObject(WXJSObject.JSON,
             data == null ? "{}" : data);
+        WXJSObject apiObj;
+        if (type == BundType.Rax) {
+          if (mRaxApi == null) {
+            mRaxApi =  WXFileUtils.loadAsset("weex-rax-api.js", WXEnvironment.getApplication());
+          }
+          apiObj = new WXJSObject(WXJSObject.String,
+                  mRaxApi);
+        } else {
+          apiObj = new WXJSObject(WXJSObject.String,
+                  "");
+        }
+
         WXJSObject[] args = {instanceIdObj, instanceObj, optionsObj,
-            dataObj};
+            dataObj, apiObj};
         instance.setTemplate(template);
-        invokeExecJS(instance.getInstanceId(), null, METHOD_CREATE_INSTANCE, args, false);
+        // if { "framework": "Vue" } or  { "framework": "Rax" } will use invokeCreateInstanceContext
+        // others will use invokeExecJS
+        if (!isSandBoxContext) {
+          invokeExecJS(instance.getInstanceId(), null, METHOD_CREATE_INSTANCE, args, false);
+          return;
+        }
+        if (type == BundType.Vue || type == BundType.Rax) {
+          invokeCreateInstanceContext(instance.getInstanceId(), null, METHOD_CREATE_INSTANCE, args, false);
+          return;
+        } else {
+          invokeExecJS(instance.getInstanceId(), null, METHOD_CREATE_INSTANCE, args, false);
+          return;
+        }
       } catch (Throwable e) {
 		String err = "[WXBridgeManager] invokeCreateInstance " + e.getCause()
 				+ instance.getTemplateInfo();
@@ -1621,6 +1764,104 @@ public class WXBridgeManager implements Callback, BactchExecutor {
     }
   }
 
+  public WXJSObject optionObjConvert(boolean useSandBox, BundType type, WXJSObject opt) {
+    if (!useSandBox || type == BundType.Others) {
+      return opt;
+    }
+    try {
+      String data = opt.data.toString();
+      JSONObject obj = JSON.parseObject(data);
+      if (obj.getJSONObject("env") != null) {
+        JSONObject optEnv = obj.getJSONObject("env");
+        // obj.replace()
+        if (optEnv != null) {
+          JSONObject opts = optEnv.getJSONObject("options");
+          if (opts!= null) {
+            optEnv.remove("options");
+            Set<String> set = opts.keySet();
+            for(Iterator it = set.iterator(); it.hasNext();) {
+              String key = it.next().toString();
+              optEnv.put(key, opts.getString(key));
+            }
+          }
+        }
+        obj.remove("env");
+        obj.put("env", optEnv);
+      }
+      WXJSObject optionsObj = new WXJSObject(WXJSObject.JSON, obj.toString());
+      return optionsObj;
+    } catch (Throwable e) {
+      e.printStackTrace();
+    }
+    return opt;
+
+  }
+
+  /**
+   * check bundleType
+   * @param url
+   * @param temp
+   * @return
+   */
+  public BundType getBundleType(String url, String temp) {
+    try {
+      if (url != null) {
+        Uri uri = Uri.parse(url);
+        String type = uri.getQueryParameter(BUNDLE_TYPE);
+        if ("Vue".equals(type) || "vue".equals(type)) {
+          return BundType.Vue;
+        } else if ("Rax".equals(type) || "rax".equals(type)) {
+          return BundType.Rax;
+        }
+      }
+      if (temp != null) {
+        if (temp.startsWith("// { \"framework\": \"Vue\" }") ||
+                temp.startsWith("// { \"framework\": \"vue\" }") ||
+                temp.startsWith("// {\"framework\" : \"Vue\"}") ||
+                temp.startsWith("// {\"framework\" : \"vue\"}")) {
+          return BundType.Vue;
+        } else if (temp.startsWith("// { \"framework\": \"Rax\" }") ||
+                temp.startsWith("// { \"framework\": \"rax\" }")
+                || temp.startsWith("// {\"framework\" : \"Rax\"}") ||
+                temp.startsWith("// {\"framework\" : \"rax\"}")) {
+          return BundType.Rax;
+        } else {
+          if (temp.length() > 500) {
+            temp = temp.substring(0, 500);
+          }
+          String strTrim = temp.replaceAll("\n","");
+          strTrim.trim();
+          if (strTrim.startsWith("// { \"framework\": \"Vue\" }") ||
+                  strTrim.startsWith("// { \"framework\": \"vue\" }") ||
+                  strTrim.startsWith("// {\"framework\" : \"Vue\"}") ||
+                  strTrim.startsWith("// {\"framework\" : \"vue\"}")) {
+            return BundType.Vue;
+          } else if (strTrim.startsWith("// { \"framework\": \"Rax\" }") ||
+                  strTrim.startsWith("// { \"framework\": \"rax\" }")
+                  || strTrim.startsWith("// {\"framework\" : \"Rax\"}") ||
+                  strTrim.startsWith("// {\"framework\" : \"rax\"}")) {
+            return BundType.Rax;
+          }
+
+          String regEx = "(use)(\\s+)(weex:vue)";
+          Pattern pattern = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
+          if (pattern.matcher(temp).find()) {
+            return BundType.Vue;
+          }
+          regEx = "(use)(\\s+)(weex:rax)";
+          pattern = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
+          if (pattern.matcher(temp).find()) {
+            return BundType.Rax;
+          }
+        }
+      }
+      return BundType.Others;
+    } catch (Throwable e) {
+      e.printStackTrace();
+      return BundType.Others;
+    }
+  }
+
   private void mock(String instanceId) {
 
   }
@@ -1657,7 +1898,8 @@ public class WXBridgeManager implements Callback, BactchExecutor {
           instanceId);
       WXJSObject[] args = {instanceIdObj};
       if (isJSFrameworkInit()) {
-        invokeExecJS(instanceId, null, METHOD_DESTROY_INSTANCE, args);
+        invokeDestoryInstance(instanceId, null, METHOD_DESTROY_INSTANCE, args, true);
+        // invokeExecJS(instanceId, null, METHOD_DESTROY_INSTANCE, args);
       }
     } catch (Throwable e) {
       String err = "[WXBridgeManager] invokeDestroyInstance " + e.getCause();
@@ -1724,6 +1966,52 @@ public class WXBridgeManager implements Callback, BactchExecutor {
       instance.callJsTime(System.currentTimeMillis()-start);
     }
   }
+  
+  public void invokeCreateInstanceContext(String instanceId, String namespace, String function,
+                                          WXJSObject[] args, boolean logTaskDetail) {
+    WXLogUtils.d("invokeCreateInstanceContext instanceId:" + instanceId + " function:"
+            + function + " isJSFrameworkInit:%d" + isJSFrameworkInit());
+    mLodBuilder.append("createInstanceContext >>>> instanceId:").append(instanceId)
+            .append("function:").append(function);
+    if (logTaskDetail)
+      mLodBuilder.append(" tasks:").append(WXJsonUtils.fromObjectToJSONString(args));
+    WXLogUtils.d(mLodBuilder.substring(0));
+    mLodBuilder.setLength(0);
+    // }
+    mWXBridge.createInstanceContext(instanceId, namespace, function, args);
+  }
+
+public void invokeDestoryInstance(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);
+    // }
+    mWXBridge.destoryInstance(instanceId, namespace, function, args);
+  }
+
+  private void execJSOnInstance(final EventResult eventCallback, final String instanceId, final String js, final int type) {
+    post(new Runnable() {
+      @Override
+      public void run() {
+        String ret = invokeExecJSOnInstance(instanceId, js, type);
+        eventCallback.onCallback(ret);
+      }
+    });
+  }
+
+  private String invokeExecJSOnInstance(String instanceId, String js, int type) {
+    // if (WXEnvironment.isApkDebugable()) {
+    mLodBuilder.append("execJSOnInstance >>>> instanceId:").append(instanceId);
+    WXLogUtils.d(mLodBuilder.substring(0));
+    mLodBuilder.setLength(0);
+    // }
+    return mWXBridge.execJSOnInstance(instanceId, js, type);
+  }
 
   private byte[] invokeExecJSWithResult(String instanceId, String namespace, String function,
                                        WXJSObject[] args,boolean logTaskDetail){
@@ -1771,7 +2059,11 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         // if (WXEnvironment.isApkDebugable()) {
         WXLogUtils.d("weex JS framework from assets");
         // }
-        framework = WXFileUtils.loadAsset("main.js", WXEnvironment.getApplication());
+        if (!isSandBoxContext) {
+          framework = WXFileUtils.loadAsset("main.js", WXEnvironment.getApplication());
+        } else {
+          framework = WXFileUtils.loadAsset("weex-main-jsfm.js", WXEnvironment.getApplication());
+        }
       }
       if (TextUtils.isEmpty(framework)) {
         setJSFrameworkInit(false);
@@ -1815,6 +2107,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
           execRegisterFailTask();
           WXEnvironment.JsFrameworkInit = true;
           registerDomModule();
+          WXModuleManager.reload();
           String reinitInfo = "";
           if (reInitCount > 1) {
             reinitInfo = "reinit Framework:";
@@ -2051,6 +2344,18 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         WXJsonUtils.fromObjectToJSONString(modules))};
     try {
       mWXBridge.execJS("", null, METHOD_REGISTER_MODULES, args);
+      try {
+        Iterator<String> iter = modules.keySet().iterator();
+        while (iter.hasNext()) {
+          String module = iter.next();
+          if (module != null) {
+            WXModuleManager.resetModuleState(module, true);
+            WXLogUtils.e("[WXBridgeManager]invokeRegisterModules METHOD_REGISTER_MODULES success module:" + module);
+          }
+
+        }
+      } catch (Throwable e) {
+      }
     } catch (Throwable e) {
 	  WXExceptionUtils.commitCriticalExceptionRT(null,
 			  WXErrorCode.WX_KEY_EXCEPTION_INVOKE_REGISTER_MODULES,

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/src/main/java/com/taobao/weex/bridge/WXModuleManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXModuleManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXModuleManager.java
index 9c6273d..5a8bb89 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXModuleManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXModuleManager.java
@@ -56,7 +56,7 @@ public class WXModuleManager {
   /**
    * module class object dictionary
    */
-  private static Map<String, ModuleFactory> sModuleFactoryMap = new HashMap<>();
+  private static volatile Map<String, ModuleFactoryImpl> sModuleFactoryMap = new HashMap<>();
   private static Map<String, WXModule> sGlobalModuleMap = new HashMap<>();
   private static Map<String, WXDomModule> sDomModuleMap = new HashMap<>();
 
@@ -81,40 +81,45 @@ public class WXModuleManager {
       return false;
     }
 
-    if (TextUtils.equals(moduleName,WXDomModule.WXDOM)) {
+    if (TextUtils.equals(moduleName, WXDomModule.WXDOM)) {
       WXLogUtils.e("Cannot registered module with name 'dom'.");
       return false;
     }
 
-    //execute task in js thread to make sure register order is same as the order invoke register method.
-    WXBridgeManager.getInstance()
-        .post(new Runnable() {
-      @Override
-      public void run() {
-        if (sModuleFactoryMap.containsKey(moduleName)) {
-          WXLogUtils.w("WXComponentRegistry Duplicate the Module name: " + moduleName);
-        }
+    try {
+      sModuleFactoryMap.put(moduleName, new ModuleFactoryImpl(factory));
+    } catch (Throwable e) {
 
-        if (global) {
-          try {
-            WXModule wxModule = factory.buildInstance();
-            wxModule.setModuleName(moduleName);
-            sGlobalModuleMap.put(moduleName, wxModule);
-          } catch (Exception e) {
-            WXLogUtils.e(moduleName + " class must have a default constructor without params. ", e);
-          }
-        }
+    }
 
-        try {
-          registerNativeModule(moduleName, factory);
-        } catch (WXException e) {
-          WXLogUtils.e("", e);
-        }
-        registerJSModule(moduleName, factory);
-      }
-    });
+    //execute task in js thread to make sure register order is same as the order invoke register method.
+    WXBridgeManager.getInstance()
+            .post(new Runnable() {
+              @Override
+              public void run() {
+                if (sModuleFactoryMap != null && sModuleFactoryMap.containsKey(moduleName)) {
+                  WXLogUtils.w("WXComponentRegistry Duplicate the Module name: " + moduleName);
+                }
+                try {
+                  registerNativeModule(moduleName, factory);
+                } catch (WXException e) {
+                  WXLogUtils.e("registerNativeModule" + e);
+                }
+
+                if (global) {
+                  try {
+                    WXModule wxModule = factory.buildInstance();
+                    wxModule.setModuleName(moduleName);
+                    sGlobalModuleMap.put(moduleName, wxModule);
+                  } catch (Exception e) {
+                    WXLogUtils.e(moduleName + " class must have a default constructor without params. ", e);
+                  }
+                }
+
+                registerJSModule(moduleName, factory);
+              }
+            });
     return true;
-
   }
 
   static boolean registerNativeModule(String moduleName, ModuleFactory factory) throws WXException {
@@ -123,12 +128,16 @@ public class WXModuleManager {
     }
 
     try {
-      sModuleFactoryMap.put(moduleName, factory);
+      if (!sModuleFactoryMap.containsKey(moduleName) ) {
+        sModuleFactoryMap.put(moduleName, new ModuleFactoryImpl(factory));
+      }
     }catch (ArrayStoreException e){
       e.printStackTrace();
       //ignore:
       //may throw this exception:
       //java.lang.String cannot be stored in an array of type java.util.HashMap$HashMapEntry[]
+
+      WXLogUtils.e("[WXModuleManager] registerNativeModule Error moduleName:"  + moduleName + " Error:" + e.toString());
     }
     return true;
   }
@@ -141,7 +150,7 @@ public class WXModuleManager {
   }
 
   static Object callModuleMethod(final String instanceId, String moduleStr, String methodStr, JSONArray args) {
-    ModuleFactory factory = sModuleFactoryMap.get(moduleStr);
+    ModuleFactory factory = sModuleFactoryMap.get(moduleStr).mFactory;
     if(factory == null){
       WXLogUtils.e("[WXModuleManager] module factory not found.");
       return null;
@@ -419,8 +428,59 @@ public class WXModuleManager {
 
   public static void reload(){
     if (sModuleFactoryMap != null && sModuleFactoryMap.size() > 0) {
-      for (Map.Entry<String, ModuleFactory> entry : sModuleFactoryMap.entrySet()) {
-        registerJSModule(entry.getKey(), entry.getValue());
+      for (Map.Entry<String, ModuleFactoryImpl> entry : sModuleFactoryMap.entrySet()) {
+        try {
+          registerJSModule(entry.getKey(), entry.getValue().mFactory);
+        } catch (Throwable e) {
+
+        }
+      }
+    }
+  }
+
+  /**
+   * registerWhenCreateInstance
+   */
+  public static void registerWhenCreateInstance(){
+    if (sModuleFactoryMap != null && sModuleFactoryMap.size() > 0) {
+      for (Map.Entry<String, ModuleFactoryImpl> entry : sModuleFactoryMap.entrySet()) {
+        try {
+          if (!entry.getValue().hasRigster) {
+            registerJSModule(entry.getKey(), entry.getValue().mFactory);
+          }
+        } catch (Throwable e) {
+
+        }
+      }
+    }
+  }
+
+  /**
+   * resetAllModuleState
+   */
+  public static void resetAllModuleState() {
+    if (sModuleFactoryMap != null && sModuleFactoryMap.size() > 0) {
+      for (Map.Entry<String, ModuleFactoryImpl> entry : sModuleFactoryMap.entrySet()) {
+        entry.getValue().hasRigster = false;
+      }
+    }
+  }
+
+  /**
+   * resetModuleState
+   * @param module
+   * @param state
+   */
+  public static void resetModuleState(String module, boolean state) {
+    if (sModuleFactoryMap != null && sModuleFactoryMap.size() > 0) {
+      for (Map.Entry<String, ModuleFactoryImpl> entry : sModuleFactoryMap.entrySet()) {
+        try {
+          if (entry.getKey() != null && entry.getKey().equals(module)) {
+            entry.getValue().hasRigster = state;
+          }
+        } catch (Throwable e) {
+
+        }
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/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 6a2a97f..0933ce3 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
@@ -61,7 +61,36 @@ public interface IWXBridge extends IWXObject {
   byte[] execJSWithResult(String instanceId, String namespace, String function, WXJSObject[] args);
 
 
+/**
+   * createInstance
+   * @param instanceId
+   * @param namespace
+   * @param function
+   * @param args
+   * @return
+   */
+  int createInstanceContext(String instanceId, String namespace, String function, WXJSObject[] args);
+
+  /**
+   * destoryInstance
+   * @param instanceId
+   * @param namespace
+   * @param function
+   * @param args
+   * @return
+   */
+  int destoryInstance(String instanceId, String namespace, String function, WXJSObject[] args);
   int execJSService(String javascript);
+  
+    /**
+   * execJSOnInstance
+   * @param instanceId
+   * @param script
+   * @param type
+   * @return
+   */
+
+  String execJSOnInstance(String instanceId, String script, int type);
 
   /**
    * take the heap snapshot and serialize the heap to a local file.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/640c53f1/android/sdk/src/main/java/com/taobao/weex/common/WXConfig.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/common/WXConfig.java b/android/sdk/src/main/java/com/taobao/weex/common/WXConfig.java
index ae1774d..11dc820 100644
--- a/android/sdk/src/main/java/com/taobao/weex/common/WXConfig.java
+++ b/android/sdk/src/main/java/com/taobao/weex/common/WXConfig.java
@@ -33,4 +33,5 @@ public interface WXConfig {
   String externalUserAgent="externalUserAgent";
   String logLevel="logLevel";
   String scale = "scale";
+  String debugMode = "debugMode";
 }