You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by so...@apache.org on 2017/06/15 07:17:37 UTC

[3/8] incubator-weex git commit: Revert "modify activity event"

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/56b18409/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 6eaac07..2db6fb3 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -18,7 +18,6 @@
  */
 package com.taobao.weex;
 
-import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -82,7 +81,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 import static com.taobao.weex.http.WXHttpUtil.KEY_USER_AGENT;
 
@@ -91,1519 +89,1478 @@ import static com.taobao.weex.http.WXHttpUtil.KEY_USER_AGENT;
  * Each instance of WXSDKInstance represents an running weex instance.
  * It can be a pure weex view, or mixed with native view
  */
-public class WXSDKInstance implements IWXActivityStateListener, DomContext, View.OnLayoutChangeListener {
-
-    //Performance
-    public boolean mEnd = false;
-    public static final String BUNDLE_URL = "bundleUrl";
-    private IWXUserTrackAdapter mUserTrackAdapter;
-    private IWXRenderListener mRenderListener;
-    private IWXStatisticsListener mStatisticsListener;
-    /**
-     * package
-     **/
-    Context mContext;
-    private final String mInstanceId;
-    private RenderContainer mRenderContainer;
-    private WXComponent mRootComp;
-    private boolean mRendered;
-    private WXRefreshData mLastRefreshData;
-    private NestedInstanceInterceptor mNestedInstanceInterceptor;
-    private String mBundleUrl = "";
-    private boolean isDestroy = false;
-    private Map<String, Serializable> mUserTrackParams;
-    private NativeInvokeHelper mNativeInvokeHelper;
-    private boolean isCommit = false;
-    private WXGlobalEventReceiver mGlobalEventReceiver = null;
-    private boolean trackComponent;
-    private boolean enableLayerType = true;
-    private boolean mNeedValidate = false;
-    private static volatile int mViewPortWidth = 750;
-    private int mInstanceViewPortWidth = 750;
-
-    /**
-     * Render strategy.
-     */
-    private WXRenderStrategy mRenderStrategy = WXRenderStrategy.APPEND_ASYNC;
-    /**
-     * Render start time
-     */
-    private long mRenderStartTime;
-    /**
-     * Refresh start time
-     */
-    private long mRefreshStartTime;
-    private WXPerformance mWXPerformance;
-    private ScrollView mScrollView;
-    private WXScrollViewListener mWXScrollViewListener;
-
-    private List<OnWXScrollListener> mWXScrollListeners;
-
-    /**
-     * whether we are in preRender mode
-     */
-    private volatile boolean isPreRenderMode;
-
-    private LayoutFinishListener mLayoutFinishListener;
-
-
-    /**
-     * If anchor is created manually(etc. define a layout xml resource ),
-     * be aware do not add it to twice when {@link IWXRenderListener#onViewCreated(WXSDKInstance, View)}.
-     *
-     * @param a
-     */
-    public void setRenderContainer(RenderContainer a) {
-        if (a != null) {
-            a.setSDKInstance(this);
-            a.addOnLayoutChangeListener(this);
-        }
-        mRenderContainer = a;
-    }
+public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.OnLayoutChangeListener {
+
+  //Performance
+  public boolean mEnd = false;
+  public static final String BUNDLE_URL = "bundleUrl";
+  private IWXUserTrackAdapter mUserTrackAdapter;
+  private IWXRenderListener mRenderListener;
+  private IWXStatisticsListener mStatisticsListener;
+  /** package **/ Context mContext;
+  private final String mInstanceId;
+  private RenderContainer mRenderContainer;
+  private WXComponent mRootComp;
+  private boolean mRendered;
+  private WXRefreshData mLastRefreshData;
+  private NestedInstanceInterceptor mNestedInstanceInterceptor;
+  private String mBundleUrl = "";
+  private boolean isDestroy=false;
+  private Map<String,Serializable> mUserTrackParams;
+  private NativeInvokeHelper mNativeInvokeHelper;
+  private boolean isCommit=false;
+  private WXGlobalEventReceiver mGlobalEventReceiver=null;
+  private boolean trackComponent;
+  private boolean enableLayerType = true;
+  private boolean mNeedValidate = false;
+  private static volatile int mViewPortWidth = 750;
+  private int mInstanceViewPortWidth = 750;
+
+  /**
+   * Render strategy.
+   */
+  private WXRenderStrategy mRenderStrategy = WXRenderStrategy.APPEND_ASYNC;
+  /**
+   * Render start time
+   */
+  private long mRenderStartTime;
+  /**
+   * Refresh start time
+   */
+  private long mRefreshStartTime;
+  private WXPerformance mWXPerformance;
+  private ScrollView mScrollView;
+  private WXScrollViewListener mWXScrollViewListener;
+
+  private List<OnWXScrollListener> mWXScrollListeners;
+
+  /**
+   * whether we are in preRender mode
+   * */
+  private volatile boolean isPreRenderMode;
+
+  private LayoutFinishListener mLayoutFinishListener;
+
+
+  /**
+   * If anchor is created manually(etc. define a layout xml resource ),
+   * be aware do not add it to twice when {@link IWXRenderListener#onViewCreated(WXSDKInstance, View)}.
+   * @param a
+   */
+  public void setRenderContainer(RenderContainer a){
+    if(a != null) {
+      a.setSDKInstance(this);
+      a.addOnLayoutChangeListener(this);
+    }
+    mRenderContainer = a;
+  }
+
+
+
+  private int mMaxDeepLayer;
+
+  public boolean isTrackComponent() {
+    return trackComponent;
+  }
+
+  public void setTrackComponent(boolean trackComponent) {
+    this.trackComponent = trackComponent;
+  }
+
+  /**
+   * Tell whether it is enabled to change the layerType
+   * {@link android.view.View#setLayerType(int, Paint)}
+   * @return True for enable to change the layerType of component, false otherwise. The default
+   * is True
+   */
+  public boolean isLayerTypeEnabled() {
+    return enableLayerType;
+  }
+
+  /**
+   * Enable the ability of changing layerType. e.g. {@link android.view.View#setLayerType(int, Paint)}
+   * Disable the ability of changing layerType will have tremendous <strong>performance
+   * punishment</strong>.
+   *
+   * <strong>Do not</strong> set this to false unless you know exactly what you are doing.
+   * @param enable True for enable to change the layerType of component, false otherwise. The default
+   * is True
+   */
+  public void enableLayerType(boolean enable) {
+    enableLayerType = enable;
+  }
+
+  public boolean isNeedValidate() {
+    return mNeedValidate;
+  }
+
+  /*
+  *  Warning: use setInstanceViewPortWidth instead.
+  *  store custom ViewPort Width
+  */
+  @Deprecated
+  public void setViewPortWidth(int viewPortWidth) {
+    mViewPortWidth = viewPortWidth;
+  }
+
+  /**
+   * Warning: use getInstanceViewPortWidth instead.
+   * @return
+   */
+  @Deprecated
+  public static int getViewPortWidth() {
+    return mViewPortWidth;
+  }
+
+  public void setInstanceViewPortWidth(int instanceViewPortWidth) {
+    this.mInstanceViewPortWidth = instanceViewPortWidth;
+  }
+
+  public int getInstanceViewPortWidth(){
+    return mInstanceViewPortWidth;
+  }
+
+  public interface OnInstanceVisibleListener{
+    void onAppear();
+    void onDisappear();
+  }
+  private List<OnInstanceVisibleListener> mVisibleListeners = new ArrayList<>();
+
+  public WXSDKInstance(Context context) {
+    mInstanceId = WXSDKManager.getInstance().generateInstanceId();
+    init(context);
+  }
+
+  /**
+   * For unittest only.
+   */
+  WXSDKInstance(Context context,String id) {
+    mInstanceId = id;
+    init(context);
+  }
+
+
+  public WXComponent getRootComponent() {
+    return mRootComp;
+  }
+
+  public void setNestedInstanceInterceptor(NestedInstanceInterceptor interceptor){
+    mNestedInstanceInterceptor = interceptor;
+  }
+
+  public WXSDKInstance createNestedInstance(NestedContainer container){
+    WXSDKInstance sdkInstance = new WXSDKInstance(mContext);
+    if(mNestedInstanceInterceptor != null){
+      mNestedInstanceInterceptor.onCreateNestInstance(sdkInstance,container);
+    }
+    return sdkInstance;
+  }
+
+  public void addOnInstanceVisibleListener(OnInstanceVisibleListener l){
+    mVisibleListeners.add(l);
+  }
+
+  public void removeOnInstanceVisibleListener(OnInstanceVisibleListener l){
+    mVisibleListeners.remove(l);
+  }
+
+  public void init(Context context) {
+    mContext = context;
+    mNativeInvokeHelper = new NativeInvokeHelper(mInstanceId);
+
+    mWXPerformance = new WXPerformance();
+    mWXPerformance.WXSDKVersion = WXEnvironment.WXSDK_VERSION;
+    mWXPerformance.JSLibInitTime = WXEnvironment.sJSLibInitTime;
+
+    mUserTrackAdapter=WXSDKManager.getInstance().getIWXUserTrackAdapter();
+  }
+
+  public NativeInvokeHelper getNativeInvokeHelper() {
+    return mNativeInvokeHelper;
+  }
+
+  public void setBizType(String bizType) {
+    if (!TextUtils.isEmpty(bizType)) {
+      mWXPerformance.bizType = bizType;
+    }
+  }
+
+  public ScrollView getScrollView() {
+    return mScrollView;
+  }
+
+  public void setRootScrollView(ScrollView scrollView) {
+    mScrollView = scrollView;
+    if (mWXScrollViewListener != null) {
+      ((WXScrollView) mScrollView).addScrollViewListener(mWXScrollViewListener);
+    }
+  }
+
+  @Deprecated
+  public void registerScrollViewListener(WXScrollViewListener scrollViewListener) {
+    mWXScrollViewListener = scrollViewListener;
+  }
+
+  @Deprecated
+  public WXScrollViewListener getScrollViewListener() {
+    return mWXScrollViewListener;
+  }
+
+  @Deprecated
+  public void setIWXUserTrackAdapter(IWXUserTrackAdapter adapter) {
+  }
+
+  /**
+   * Render template asynchronously, use {@link WXRenderStrategy#APPEND_ASYNC} as render strategy
+   * @param template bundle js
+   * @param options  os   iphone/android/ipad
+   *                 weexversion    Weex version(like 1.0.0)
+   *                 appversion     App version(like 1.0.0)
+   *                 devid        Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
+   *                 sysversion    Device system version(like 5.4.4、7.0.4, should be used with os)
+   *                 sysmodel     Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
+   *                 Time    UNIX timestamp, UTC+08:00
+   *                 TTID(Optional)
+   *                 MarkertId
+   *                 Appname(Optional)  tm,tb,qa
+   *                 Bundleurl(Optional)  template url
+   * @param jsonInitData Initial data for rendering
+   */
+  public void render(String template, Map<String, Object> options, String jsonInitData) {
+    render(template, options, jsonInitData, WXRenderStrategy.APPEND_ASYNC);
+  }
+
+  /**
+   * Render template asynchronously
+   * @param template bundle js
+   * @param options  os   iphone/android/ipad
+   *                 weexversion    Weex version(like 1.0.0)
+   *                 appversion     App version(like 1.0.0)
+   *                 devid        Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
+   *                 sysversion    Device system version(like 5.4.4、7.0.4, should be used with os)
+   *                 sysmodel     Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
+   *                 Time    UNIX timestamp, UTC+08:00
+   *                 TTID(Optional)
+   *                 MarkertId
+   *                 Appname(Optional)  tm,tb,qa
+   *                 Bundleurl(Optional)  template url
+   * @param jsonInitData Initial data for rendering
+   * @param flag     RenderStrategy {@link WXRenderStrategy}
+   */
+  @Deprecated
+  public void render(String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
+    render(WXPerformance.DEFAULT, template, options, jsonInitData, flag);
+  }
+
+  /**
+   * Render template asynchronously
+   *
+   * @param pageName, used for performance log.
+   * @param template bundle js
+   * @param options  os   iphone/android/ipad
+   *                 weexversion    Weex version(like 1.0.0)
+   *                 appversion     App version(like 1.0.0)
+   *                 devid        Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
+   *                 sysversion    Device system version(like 5.4.4、7.0.4, should be used with os)
+   *                 sysmodel     Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
+   *                 Time    UNIX timestamp, UTC+08:00
+   *                 TTID(Optional)
+   *                 MarkertId
+   *                 Appname(Optional)  tm,tb,qa
+   *                 Bundleurl(Optional)  template url
+   * @param jsonInitData Initial data for rendering
+   * @param flag     RenderStrategy {@link WXRenderStrategy}
+   */
+  public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
+    if(WXEnvironment.isApkDebugable() && WXPerformance.DEFAULT.equals(pageName)){
+       WXLogUtils.e("Please set your pageName or your js bundle url !!!!!!!");
+       return;
+    }
+    renderInternal(pageName,template,options,jsonInitData,flag);
+  }
+
+  private void ensureRenderArchor(){
+    if(mRenderContainer == null){
+      mRenderContainer = new RenderContainer(getContext());
+      mRenderContainer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+      mRenderContainer.setBackgroundColor(Color.TRANSPARENT);
+      mRenderContainer.setSDKInstance(this);
+      mRenderContainer.addOnLayoutChangeListener(this);
+    }
+  }
+
+  private void renderInternal(String pageName,
+                              String template,
+                              Map<String, Object> options,
+                              String jsonInitData,
+                              WXRenderStrategy flag){
+    if (mRendered || TextUtils.isEmpty(template)) {
+      return;
+    }
+
+    ensureRenderArchor();
+
+    Map<String, Object> renderOptions = options;
+    if (renderOptions == null) {
+      renderOptions = new HashMap<>();
+    }
+
+    if (WXEnvironment.sDynamicMode && !TextUtils.isEmpty(WXEnvironment.sDynamicUrl) && renderOptions.get("dynamicMode") == null) {
+      renderOptions.put("dynamicMode", "true");
+      renderByUrl(pageName, WXEnvironment.sDynamicUrl, renderOptions, jsonInitData, flag);
+      return;
+    }
+
+    mWXPerformance.pageName = pageName;
+    mWXPerformance.JSTemplateSize = template.length() / 1024;
+
+    mRenderStartTime = System.currentTimeMillis();
+    mRenderStrategy = flag;
+
+    WXSDKManager.getInstance().setCrashInfo(WXEnvironment.WEEX_CURRENT_KEY,pageName);
+
+    WXSDKManager.getInstance().createInstance(this, template, renderOptions, jsonInitData);
+    mRendered = true;
+
+    if (TextUtils.isEmpty(mBundleUrl)) {
+      mBundleUrl = pageName;
+    }
+  }
+
+  private void renderByUrlInternal(String pageName,
+                                   final String url,
+                                   Map<String, Object> options,
+                                   final String jsonInitData,
+                                   final WXRenderStrategy flag) {
+
+    ensureRenderArchor();
+    pageName = wrapPageName(pageName, url);
+    mBundleUrl = url;
+    if(WXSDKManager.getInstance().getValidateProcessor()!=null) {
+      mNeedValidate = WXSDKManager.getInstance().getValidateProcessor().needValidate(mBundleUrl);
+    }
+
+    Map<String, Object> renderOptions = options;
+    if (renderOptions == null) {
+      renderOptions = new HashMap<>();
+    }
+    if (!renderOptions.containsKey(BUNDLE_URL)) {
+      renderOptions.put(BUNDLE_URL, url);
+    }
+
+    Uri uri = Uri.parse(url);
+    if (uri != null && TextUtils.equals(uri.getScheme(), "file")) {
+      render(pageName, WXFileUtils.loadFileOrAsset(assembleFilePath(uri), mContext), renderOptions, jsonInitData, flag);
+      return;
+    }
+
+    IWXHttpAdapter adapter = WXSDKManager.getInstance().getIWXHttpAdapter();
+
+    WXRequest wxRequest = new WXRequest();
+    wxRequest.url = rewriteUri(Uri.parse(url),URIAdapter.BUNDLE).toString();
+    if (wxRequest.paramMap == null) {
+      wxRequest.paramMap = new HashMap<String, String>();
+    }
+    wxRequest.paramMap.put(KEY_USER_AGENT, WXHttpUtil.assembleUserAgent(mContext,WXEnvironment.getConfig()));
+    WXHttpListener httpListener =
+        new WXHttpListener(pageName, renderOptions, jsonInitData, flag, System.currentTimeMillis());
+    httpListener.setSDKInstance(this);
+    adapter.sendRequest(wxRequest, (IWXHttpAdapter.OnHttpListener) httpListener);
+  }
+
+  /**
+   * Use {@link #render(String, String, Map, String, WXRenderStrategy)} instead.
+   * @param pageName
+   * @param template
+   * @param options
+   * @param jsonInitData
+   * @param width
+   * @param height
+   * @param flag
+   */
+  @Deprecated
+  public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, int width, int height, WXRenderStrategy flag) {
+    render(pageName,template,options,jsonInitData,flag);
+  }
+
+  /**
+   * Render template asynchronously, use {@link WXRenderStrategy#APPEND_ASYNC} as render strategy
+   * @param template bundle js
+   */
+  public void render(String template) {
+    render(WXPerformance.DEFAULT, template, null, null, mRenderStrategy);
+  }
+
+  /**
+   * Use {@link #render(String)} instead.
+   * @param template
+   * @param width
+   * @param height
+   */
+  @Deprecated
+  public void render(String template, int width, int height) {
+    render(template);
+  }
+
+  /**
+   * Use {@link #renderByUrl(String, String, Map, String, WXRenderStrategy)} instead.
+   * @param pageName
+   * @param url
+   * @param options
+   * @param jsonInitData
+   * @param width
+   * @param height
+   * @param flag
+   */
+  @Deprecated
+  public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final int width, final int height, final WXRenderStrategy flag){
+    renderByUrl(pageName,url,options,jsonInitData,flag);
+  }
+
+  public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final WXRenderStrategy flag) {
+    renderByUrlInternal(pageName,url,options,jsonInitData,flag);
+  }
+
+  private String wrapPageName(String pageName, String url) {
+    if(TextUtils.equals(pageName, WXPerformance.DEFAULT)){
+      pageName=url;
+      try {
+        Uri uri=Uri.parse(url);
+        if(uri!=null){
+          Uri.Builder builder=new Uri.Builder();
+          builder.scheme(uri.getScheme());
+          builder.authority(uri.getAuthority());
+          builder.path(uri.getPath());
+          pageName=builder.toString();
+        }
+      } catch (Exception e) {
+      }
+    }
+    return pageName;
+  }
+
+  private String assembleFilePath(Uri uri) {
+    if(uri!=null && uri.getPath()!=null){
+      return uri.getPath().replaceFirst("/","");
+    }
+    return "";
+  }
+
+  /**
+   * Refresh instance asynchronously.
+   * @param data the new data
+   */
+  public void refreshInstance(Map<String, Object> data) {
+    if (data == null) {
+      return;
+    }
+    refreshInstance(WXJsonUtils.fromObjectToJSONString(data));
+  }
+
+  /**
+   * Refresh instance asynchronously.
+   * @param jsonData the new data
+   */
+  public void refreshInstance(String jsonData) {
+    if (jsonData == null) {
+      return;
+    }
+    mRefreshStartTime = System.currentTimeMillis();
+    //cancel last refresh message
+    if (mLastRefreshData != null) {
+      mLastRefreshData.isDirty = true;
+    }
+
+    mLastRefreshData = new WXRefreshData(jsonData, false);
+
+    WXSDKManager.getInstance().refreshInstance(mInstanceId, mLastRefreshData);
+  }
+
+  public WXRenderStrategy getRenderStrategy() {
+    return mRenderStrategy;
+  }
+
+  @Override
+  public Context getUIContext() {
+    return mContext;
+  }
+
+  public String getInstanceId() {
+    return mInstanceId;
+  }
+
+  public Context getContext() {
+    if(mContext == null){
+      WXLogUtils.e("WXSdkInstance mContext == null");
+    }
+    return mContext;
+  }
+
+  public int getWeexHeight() {
+    return mRenderContainer == null ? 0: mRenderContainer.getHeight();
+  }
+
+  public int getWeexWidth() {
+    return mRenderContainer == null ? 0: mRenderContainer.getWidth();
+  }
+
+
+  public IWXImgLoaderAdapter getImgLoaderAdapter() {
+    return WXSDKManager.getInstance().getIWXImgLoaderAdapter();
+  }
+
+  public IDrawableLoader getDrawableLoader() {
+    return WXSDKManager.getInstance().getDrawableLoader();
+  }
 
+  public URIAdapter getURIAdapter(){
+    return WXSDKManager.getInstance().getURIAdapter();
+  }
 
-    private int mMaxDeepLayer;
+  public Uri rewriteUri(Uri uri,String type){
+    return getURIAdapter().rewrite(this,type,uri);
+  }
 
-    public boolean isTrackComponent() {
-        return trackComponent;
-    }
-
-    public void setTrackComponent(boolean trackComponent) {
-        this.trackComponent = trackComponent;
-    }
+  public IWXHttpAdapter getWXHttpAdapter() {
+    return WXSDKManager.getInstance().getIWXHttpAdapter();
+  }
 
-    /**
-     * Tell whether it is enabled to change the layerType
-     * {@link android.view.View#setLayerType(int, Paint)}
-     *
-     * @return True for enable to change the layerType of component, false otherwise. The default
-     * is True
-     */
-    public boolean isLayerTypeEnabled() {
-        return enableLayerType;
-    }
+  public IWXStatisticsListener getWXStatisticsListener() {
+    return mStatisticsListener;
+  }
 
-    /**
-     * Enable the ability of changing layerType. e.g. {@link android.view.View#setLayerType(int, Paint)}
-     * Disable the ability of changing layerType will have tremendous <strong>performance
-     * punishment</strong>.
-     * <p>
-     * <strong>Do not</strong> set this to false unless you know exactly what you are doing.
-     *
-     * @param enable True for enable to change the layerType of component, false otherwise. The default
-     *               is True
-     */
-    public void enableLayerType(boolean enable) {
-        enableLayerType = enable;
-    }
+  public @Nullable
+  IWebSocketAdapter getWXWebSocketAdapter() {
+    return WXSDKManager.getInstance().getIWXWebSocketAdapter();
+  }
 
-    public boolean isNeedValidate() {
-        return mNeedValidate;
+  @Deprecated
+  public void reloadImages() {
+    if (mScrollView == null) {
+      return;
     }
+  }
 
-    /*
-    *  Warning: use setInstanceViewPortWidth instead.
-    *  store custom ViewPort Width
-    */
-    @Deprecated
-    public void setViewPortWidth(int viewPortWidth) {
-        mViewPortWidth = viewPortWidth;
-    }
 
-    /**
-     * Warning: use getInstanceViewPortWidth instead.
-     *
-     * @return
-     */
-    @Deprecated
-    public static int getViewPortWidth() {
-        return mViewPortWidth;
-    }
+  public boolean isPreRenderMode() {
+    return this.isPreRenderMode;
+  }
 
-    public void setInstanceViewPortWidth(int instanceViewPortWidth) {
-        this.mInstanceViewPortWidth = instanceViewPortWidth;
-    }
+  public void setPreRenderMode(final boolean isPreRenderMode) {
+    WXSDKManager.getInstance().getWXRenderManager().postOnUiThread(new Runnable() {
+      @Override
+      public void run() {
+        WXSDKInstance.this.isPreRenderMode = isPreRenderMode;
+      }
+    },0);
+  }
 
-    public int getInstanceViewPortWidth() {
-        return mInstanceViewPortWidth;
-    }
+  public void setContext(@NonNull Context context) {
+    this.mContext = context;
+  }
 
-    public interface OnInstanceVisibleListener {
-        void onAppear();
+  /********************************
+   * begin register listener
+   ********************************************************/
+  public void registerRenderListener(IWXRenderListener listener) {
+    mRenderListener = listener;
+  }
 
-        void onDisappear();
-    }
+  @Deprecated
+  public void registerActivityStateListener(IWXActivityStateListener listener) {
 
-    private List<OnInstanceVisibleListener> mVisibleListeners = new ArrayList<>();
+  }
 
-    public WXSDKInstance(Context context) {
-        mInstanceId = WXSDKManager.getInstance().generateInstanceId();
-        init(context);
-    }
+  public void registerStatisticsListener(IWXStatisticsListener listener) {
+    mStatisticsListener = listener;
+  }
 
-    /**
-     * For unittest only.
-     */
-    WXSDKInstance(Context context, String id) {
-        mInstanceId = id;
-        init(context);
-    }
+  public void setLayoutFinishListener(@Nullable LayoutFinishListener listener) {
+    this.mLayoutFinishListener = listener;
+  }
 
+  public LayoutFinishListener getLayoutFinishListener() {
+    return this.mLayoutFinishListener;
+  }
 
-    public WXComponent getRootComponent() {
-        return mRootComp;
-    }
 
-    public void setNestedInstanceInterceptor(NestedInstanceInterceptor interceptor) {
-        mNestedInstanceInterceptor = interceptor;
-    }
+  /**set render start time*/
+  public void setRenderStartTime(long renderStartTime) {
+    this.mRenderStartTime = renderStartTime;
+  }
 
-    public WXSDKInstance createNestedInstance(NestedContainer container) {
-        WXSDKInstance sdkInstance = new WXSDKInstance(mContext);
-        if (mNestedInstanceInterceptor != null) {
-            mNestedInstanceInterceptor.onCreateNestInstance(sdkInstance, container);
-        }
-        return sdkInstance;
-    }
+  /********************************
+   * end register listener
+   ********************************************************/
 
-    public void addOnInstanceVisibleListener(OnInstanceVisibleListener l) {
-        mVisibleListeners.add(l);
-    }
 
-    public void removeOnInstanceVisibleListener(OnInstanceVisibleListener l) {
-        mVisibleListeners.remove(l);
-    }
+  /********************************
+   *  begin hook Activity life cycle callback
+   ********************************************************/
 
-    private ActivityManager mActivityManager;
+  @Override
+  public void onActivityCreate() {
 
-    public void init(Context context) {
-        mContext = context;
-        mNativeInvokeHelper = new NativeInvokeHelper(mInstanceId);
-
-        mWXPerformance = new WXPerformance();
-        mWXPerformance.WXSDKVersion = WXEnvironment.WXSDK_VERSION;
-        mWXPerformance.JSLibInitTime = WXEnvironment.sJSLibInitTime;
-
-        mUserTrackAdapter = WXSDKManager.getInstance().getIWXUserTrackAdapter();
+    // module listen Activity onActivityCreate
+    WXModuleManager.onActivityCreate(getInstanceId());
 
+    if(mRootComp != null) {
+      mRootComp.onActivityCreate();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely,onActivityCreate can not be call!");
     }
 
-    public NativeInvokeHelper getNativeInvokeHelper() {
-        return mNativeInvokeHelper;
-    }
-
-    public void setBizType(String bizType) {
-        if (!TextUtils.isEmpty(bizType)) {
-            mWXPerformance.bizType = bizType;
-        }
-    }
+    mGlobalEventReceiver=new WXGlobalEventReceiver(this);
+    getContext().registerReceiver(mGlobalEventReceiver,new IntentFilter(WXGlobalEventReceiver.EVENT_ACTION));
+  }
 
-    public ScrollView getScrollView() {
-        return mScrollView;
-    }
+  @Override
+  public void onActivityStart() {
 
-    public void setRootScrollView(ScrollView scrollView) {
-        mScrollView = scrollView;
-        if (mWXScrollViewListener != null) {
-            ((WXScrollView) mScrollView).addScrollViewListener(mWXScrollViewListener);
-        }
+    // module listen Activity onActivityCreate
+    WXModuleManager.onActivityStart(getInstanceId());
+    if(mRootComp != null) {
+      mRootComp.onActivityStart();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely,onActivityStart can not be call!");
     }
 
-    @Deprecated
-    public void registerScrollViewListener(WXScrollViewListener scrollViewListener) {
-        mWXScrollViewListener = scrollViewListener;
-    }
-
-    @Deprecated
-    public WXScrollViewListener getScrollViewListener() {
-        return mWXScrollViewListener;
-    }
-
-    @Deprecated
-    public void setIWXUserTrackAdapter(IWXUserTrackAdapter adapter) {
-    }
-
-    /**
-     * Render template asynchronously, use {@link WXRenderStrategy#APPEND_ASYNC} as render strategy
-     *
-     * @param template     bundle js
-     * @param options      os   iphone/android/ipad
-     *                     weexversion    Weex version(like 1.0.0)
-     *                     appversion     App version(like 1.0.0)
-     *                     devid        Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
-     *                     sysversion    Device system version(like 5.4.4、7.0.4, should be used with os)
-     *                     sysmodel     Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
-     *                     Time    UNIX timestamp, UTC+08:00
-     *                     TTID(Optional)
-     *                     MarkertId
-     *                     Appname(Optional)  tm,tb,qa
-     *                     Bundleurl(Optional)  template url
-     * @param jsonInitData Initial data for rendering
-     */
-    public void render(String template, Map<String, Object> options, String jsonInitData) {
-        render(template, options, jsonInitData, WXRenderStrategy.APPEND_ASYNC);
-    }
-
-    /**
-     * Render template asynchronously
-     *
-     * @param template     bundle js
-     * @param options      os   iphone/android/ipad
-     *                     weexversion    Weex version(like 1.0.0)
-     *                     appversion     App version(like 1.0.0)
-     *                     devid        Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
-     *                     sysversion    Device system version(like 5.4.4、7.0.4, should be used with os)
-     *                     sysmodel     Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
-     *                     Time    UNIX timestamp, UTC+08:00
-     *                     TTID(Optional)
-     *                     MarkertId
-     *                     Appname(Optional)  tm,tb,qa
-     *                     Bundleurl(Optional)  template url
-     * @param jsonInitData Initial data for rendering
-     * @param flag         RenderStrategy {@link WXRenderStrategy}
-     */
-    @Deprecated
-    public void render(String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
-        render(WXPerformance.DEFAULT, template, options, jsonInitData, flag);
-    }
-
-    /**
-     * Render template asynchronously
-     *
-     * @param pageName,    used for performance log.
-     * @param template     bundle js
-     * @param options      os   iphone/android/ipad
-     *                     weexversion    Weex version(like 1.0.0)
-     *                     appversion     App version(like 1.0.0)
-     *                     devid        Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
-     *                     sysversion    Device system version(like 5.4.4、7.0.4, should be used with os)
-     *                     sysmodel     Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
-     *                     Time    UNIX timestamp, UTC+08:00
-     *                     TTID(Optional)
-     *                     MarkertId
-     *                     Appname(Optional)  tm,tb,qa
-     *                     Bundleurl(Optional)  template url
-     * @param jsonInitData Initial data for rendering
-     * @param flag         RenderStrategy {@link WXRenderStrategy}
-     */
-    public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
-        if (WXEnvironment.isApkDebugable() && WXPerformance.DEFAULT.equals(pageName)) {
-            WXLogUtils.e("Please set your pageName or your js bundle url !!!!!!!");
-            return;
-        }
-        renderInternal(pageName, template, options, jsonInitData, flag);
-    }
-
-    private void ensureRenderArchor() {
-        if (mRenderContainer == null) {
-            mRenderContainer = new RenderContainer(getContext());
-            mRenderContainer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-            mRenderContainer.setBackgroundColor(Color.TRANSPARENT);
-            mRenderContainer.setSDKInstance(this);
-            mRenderContainer.addOnLayoutChangeListener(this);
-        }
-    }
-
-    private void renderInternal(String pageName,
-                                String template,
-                                Map<String, Object> options,
-                                String jsonInitData,
-                                WXRenderStrategy flag) {
-        if (mRendered || TextUtils.isEmpty(template)) {
-            return;
-        }
-
-        ensureRenderArchor();
-
-        Map<String, Object> renderOptions = options;
-        if (renderOptions == null) {
-            renderOptions = new HashMap<>();
-        }
-
-        if (WXEnvironment.sDynamicMode && !TextUtils.isEmpty(WXEnvironment.sDynamicUrl) && renderOptions.get("dynamicMode") == null) {
-            renderOptions.put("dynamicMode", "true");
-            renderByUrl(pageName, WXEnvironment.sDynamicUrl, renderOptions, jsonInitData, flag);
-            return;
-        }
-
-        mWXPerformance.pageName = pageName;
-        mWXPerformance.JSTemplateSize = template.length() / 1024;
-
-        mRenderStartTime = System.currentTimeMillis();
-        mRenderStrategy = flag;
+  }
 
-        WXSDKManager.getInstance().setCrashInfo(WXEnvironment.WEEX_CURRENT_KEY, pageName);
+  public boolean onCreateOptionsMenu(Menu menu) {
 
-        WXSDKManager.getInstance().createInstance(this, template, renderOptions, jsonInitData);
-        mRendered = true;
-
-        if (TextUtils.isEmpty(mBundleUrl)) {
-            mBundleUrl = pageName;
-        }
+    WXModuleManager.onCreateOptionsMenu(getInstanceId(),menu);
+    if(mRootComp != null) {
+      mRootComp.onCreateOptionsMenu(menu);
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely,onActivityStart can not be call!");
     }
+    return true;
+  }
 
-    private void renderByUrlInternal(String pageName,
-                                     final String url,
-                                     Map<String, Object> options,
-                                     final String jsonInitData,
-                                     final WXRenderStrategy flag) {
-
-        ensureRenderArchor();
-        pageName = wrapPageName(pageName, url);
-        mBundleUrl = url;
-        if (WXSDKManager.getInstance().getValidateProcessor() != null) {
-            mNeedValidate = WXSDKManager.getInstance().getValidateProcessor().needValidate(mBundleUrl);
-        }
-
-        Map<String, Object> renderOptions = options;
-        if (renderOptions == null) {
-            renderOptions = new HashMap<>();
-        }
-        if (!renderOptions.containsKey(BUNDLE_URL)) {
-            renderOptions.put(BUNDLE_URL, url);
-        }
-
-        Uri uri = Uri.parse(url);
-        if (uri != null && TextUtils.equals(uri.getScheme(), "file")) {
-            render(pageName, WXFileUtils.loadFileOrAsset(assembleFilePath(uri), mContext), renderOptions, jsonInitData, flag);
-            return;
-        }
-
-        IWXHttpAdapter adapter = WXSDKManager.getInstance().getIWXHttpAdapter();
-
-        WXRequest wxRequest = new WXRequest();
-        wxRequest.url = rewriteUri(Uri.parse(url), URIAdapter.BUNDLE).toString();
-        if (wxRequest.paramMap == null) {
-            wxRequest.paramMap = new HashMap<String, String>();
-        }
-        wxRequest.paramMap.put(KEY_USER_AGENT, WXHttpUtil.assembleUserAgent(mContext, WXEnvironment.getConfig()));
-        WXHttpListener httpListener =
-                new WXHttpListener(pageName, renderOptions, jsonInitData, flag, System.currentTimeMillis());
-        httpListener.setSDKInstance(this);
-        adapter.sendRequest(wxRequest, (IWXHttpAdapter.OnHttpListener) httpListener);
-    }
-
-    /**
-     * Use {@link #render(String, String, Map, String, WXRenderStrategy)} instead.
-     *
-     * @param pageName
-     * @param template
-     * @param options
-     * @param jsonInitData
-     * @param width
-     * @param height
-     * @param flag
-     */
-    @Deprecated
-    public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, int width, int height, WXRenderStrategy flag) {
-        render(pageName, template, options, jsonInitData, flag);
+  @Override
+  public void onActivityPause() {
+    onViewDisappear();
+    if(!isCommit){
+      Set<String> componentTypes= WXComponentFactory.getComponentTypesByInstanceId(getInstanceId());
+      if(componentTypes!=null && componentTypes.contains(WXBasicComponentType.SCROLLER)){
+        mWXPerformance.useScroller=1;
+      }
+      mWXPerformance.maxDeepViewLayer=getMaxDeepLayer();
+      if (mUserTrackAdapter != null) {
+        mUserTrackAdapter.commit(mContext, null, IWXUserTrackAdapter.LOAD, mWXPerformance, getUserTrackParams());
+      }
+      isCommit=true;
     }
-
-    /**
-     * Render template asynchronously, use {@link WXRenderStrategy#APPEND_ASYNC} as render strategy
-     *
-     * @param template bundle js
-     */
-    public void render(String template) {
-        render(WXPerformance.DEFAULT, template, null, null, mRenderStrategy);
-    }
-
-    /**
-     * Use {@link #render(String)} instead.
-     *
-     * @param template
-     * @param width
-     * @param height
-     */
-    @Deprecated
-    public void render(String template, int width, int height) {
-        render(template);
-    }
-
-    /**
-     * Use {@link #renderByUrl(String, String, Map, String, WXRenderStrategy)} instead.
-     *
-     * @param pageName
-     * @param url
-     * @param options
-     * @param jsonInitData
-     * @param width
-     * @param height
-     * @param flag
-     */
-    @Deprecated
-    public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final int width, final int height, final WXRenderStrategy flag) {
-        renderByUrl(pageName, url, options, jsonInitData, flag);
-    }
-
-    public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final WXRenderStrategy flag) {
-        renderByUrlInternal(pageName, url, options, jsonInitData, flag);
-    }
-
-    private String wrapPageName(String pageName, String url) {
-        if (TextUtils.equals(pageName, WXPerformance.DEFAULT)) {
-            pageName = url;
-            try {
-                Uri uri = Uri.parse(url);
-                if (uri != null) {
-                    Uri.Builder builder = new Uri.Builder();
-                    builder.scheme(uri.getScheme());
-                    builder.authority(uri.getAuthority());
-                    builder.path(uri.getPath());
-                    pageName = builder.toString();
-                }
-            } catch (Exception e) {
-            }
-        }
-        return pageName;
+    // module listen Activity onActivityPause
+    WXModuleManager.onActivityPause(getInstanceId());
+    if(mRootComp != null) {
+      mRootComp.onActivityPause();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely,onActivityPause can not be call!");
     }
 
-    private String assembleFilePath(Uri uri) {
-        if (uri != null && uri.getPath() != null) {
-            return uri.getPath().replaceFirst("/", "");
-        }
-        return "";
-    }
+    Intent intent=new Intent(WXGlobalEventReceiver.EVENT_ACTION);
+    intent.putExtra(WXGlobalEventReceiver.EVENT_NAME,Constants.Event.PAUSE_EVENT);
+    intent.putExtra(WXGlobalEventReceiver.EVENT_WX_INSTANCEID,getInstanceId());
+    mContext.sendBroadcast(intent);
+  }
 
-    /**
-     * Refresh instance asynchronously.
-     *
-     * @param data the new data
-     */
-    public void refreshInstance(Map<String, Object> data) {
-        if (data == null) {
-            return;
-        }
-        refreshInstance(WXJsonUtils.fromObjectToJSONString(data));
-    }
 
-    /**
-     * Refresh instance asynchronously.
-     *
-     * @param jsonData the new data
-     */
-    public void refreshInstance(String jsonData) {
-        if (jsonData == null) {
-            return;
-        }
-        mRefreshStartTime = System.currentTimeMillis();
-        //cancel last refresh message
-        if (mLastRefreshData != null) {
-            mLastRefreshData.isDirty = true;
-        }
+  @Override
+  public void onActivityResume() {
 
-        mLastRefreshData = new WXRefreshData(jsonData, false);
+    // notify onActivityResume callback to module
+    WXModuleManager.onActivityResume(getInstanceId());
 
-        WXSDKManager.getInstance().refreshInstance(mInstanceId, mLastRefreshData);
+    if(mRootComp != null) {
+      mRootComp.onActivityResume();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely, onActivityResume can not be call!");
     }
 
-    public WXRenderStrategy getRenderStrategy() {
-        return mRenderStrategy;
-    }
+    Intent intent=new Intent(WXGlobalEventReceiver.EVENT_ACTION);
+    intent.putExtra(WXGlobalEventReceiver.EVENT_NAME,Constants.Event.RESUME_EVENT);
+    intent.putExtra(WXGlobalEventReceiver.EVENT_WX_INSTANCEID,getInstanceId());
+    mContext.sendBroadcast(intent);
 
-    @Override
-    public Context getUIContext() {
-        return mContext;
-    }
+    onViewAppear();
 
-    public String getInstanceId() {
-        return mInstanceId;
-    }
+    setViewPortWidth(mInstanceViewPortWidth);
+  }
 
-    public Context getContext() {
-        if (mContext == null) {
-            WXLogUtils.e("WXSdkInstance mContext == null");
-        }
-        return mContext;
-    }
+  @Override
+  public void onActivityStop() {
 
-    public int getWeexHeight() {
-        return mRenderContainer == null ? 0 : mRenderContainer.getHeight();
-    }
+    // notify onActivityResume callback to module
+    WXModuleManager.onActivityStop(getInstanceId());
 
-    public int getWeexWidth() {
-        return mRenderContainer == null ? 0 : mRenderContainer.getWidth();
+    if(mRootComp != null) {
+      mRootComp.onActivityStop();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely, onActivityStop can not be call!");
     }
 
 
-    public IWXImgLoaderAdapter getImgLoaderAdapter() {
-        return WXSDKManager.getInstance().getIWXImgLoaderAdapter();
-    }
+  }
 
-    public IDrawableLoader getDrawableLoader() {
-        return WXSDKManager.getInstance().getDrawableLoader();
-    }
+  @Override
+  public void onActivityDestroy() {
+    WXModuleManager.onActivityDestroy(getInstanceId());
 
-    public URIAdapter getURIAdapter() {
-        return WXSDKManager.getInstance().getURIAdapter();
+    if(mRootComp != null) {
+      mRootComp.onActivityDestroy();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely, onActivityDestroy can not be call!");
     }
 
-    public Uri rewriteUri(Uri uri, String type) {
-        return getURIAdapter().rewrite(this, type, uri);
-    }
+    destroy();
+  }
 
-    public IWXHttpAdapter getWXHttpAdapter() {
-        return WXSDKManager.getInstance().getIWXHttpAdapter();
-    }
+  @Override
+  public boolean onActivityBack() {
 
-    public IWXStatisticsListener getWXStatisticsListener() {
-        return mStatisticsListener;
-    }
+    WXModuleManager.onActivityBack(getInstanceId());
 
-    public
-    @Nullable
-    IWebSocketAdapter getWXWebSocketAdapter() {
-        return WXSDKManager.getInstance().getIWXWebSocketAdapter();
-    }
-
-    @Deprecated
-    public void reloadImages() {
-        if (mScrollView == null) {
-            return;
-        }
+    if(mRootComp != null) {
+      return mRootComp.onActivityBack();
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely, onActivityBack can not be call!");
     }
 
+    return false;
+  }
 
-    public boolean isPreRenderMode() {
-        return this.isPreRenderMode;
+  public boolean onBackPressed() {
+    WXComponent comp = getRootComponent();
+    if(comp != null) {
+      WXEvent events= comp.getDomObject().getEvents();
+      boolean hasBackPressed = events.contains(Constants.Event.CLICKBACKITEM);
+      if (hasBackPressed) {
+        WXBridgeManager.getInstance().fireEvent(this.mInstanceId, comp.getRef(), Constants.Event.CLICKBACKITEM,null, null);
+      }
+      return hasBackPressed;
     }
+    return false;
+  }
 
-    public void setPreRenderMode(final boolean isPreRenderMode) {
-        WXSDKManager.getInstance().getWXRenderManager().postOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                WXSDKInstance.this.isPreRenderMode = isPreRenderMode;
-            }
-        }, 0);
-    }
+    public void onActivityResult(int requestCode, int resultCode, Intent data){
+    WXModuleManager.onActivityResult(getInstanceId(),requestCode,resultCode,data);
 
-    public void setContext(@NonNull Context context) {
-        this.mContext = context;
+    if(mRootComp != null) {
+      mRootComp.onActivityResult(requestCode,resultCode,data);
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely, onActivityResult can not be call!");
     }
+  }
 
-    /********************************
-     * begin register listener
-     ********************************************************/
-    public void registerRenderListener(IWXRenderListener listener) {
-        mRenderListener = listener;
-    }
 
-    @Deprecated
-    public void registerActivityStateListener(IWXActivityStateListener listener) {
+  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
 
-    }
+    WXModuleManager.onRequestPermissionsResult(getInstanceId(),requestCode,permissions,grantResults);
 
-    public void registerStatisticsListener(IWXStatisticsListener listener) {
-        mStatisticsListener = listener;
+    if(mRootComp != null) {
+       mRootComp.onRequestPermissionsResult(requestCode,permissions,grantResults);
+    }else{
+      WXLogUtils.w("Warning :Component tree has not build completely, onRequestPermissionsResult can not be call!");
     }
+  }
 
-    public void setLayoutFinishListener(@Nullable LayoutFinishListener listener) {
-        this.mLayoutFinishListener = listener;
-    }
+  /********************************
+   *  end hook Activity life cycle callback
+   ********************************************************/
 
-    public LayoutFinishListener getLayoutFinishListener() {
-        return this.mLayoutFinishListener;
+  public void onViewDisappear(){
+    WXComponent comp = getRootComponent();
+    if(comp != null) {
+      WXBridgeManager.getInstance().fireEvent(this.mInstanceId, comp.getRef(), Constants.Event.VIEWDISAPPEAR, null, null);
+      //call disappear of nested instances
+      for(OnInstanceVisibleListener instance:mVisibleListeners){
+        instance.onDisappear();
+      }
     }
+  }
 
-
-    /**
-     * set render start time
-     */
-    public void setRenderStartTime(long renderStartTime) {
-        this.mRenderStartTime = renderStartTime;
+  public void onViewAppear(){
+    WXComponent comp = getRootComponent();
+    if(comp != null) {
+      WXBridgeManager.getInstance().fireEvent(this.mInstanceId, comp.getRef(), Constants.Event.VIEWAPPEAR,null, null);
+      for(OnInstanceVisibleListener instance:mVisibleListeners){
+        instance.onAppear();
+      }
     }
-
-    /********************************
-     * end register listener
-     ********************************************************/
+  }
 
 
-    /********************************
-     *  begin hook Activity life cycle callback
-     ********************************************************/
-
-    @Override
-    public void onActivityCreate() {
-
-        // module listen Activity onActivityCreate
-        WXModuleManager.onActivityCreate(getInstanceId());
-
-        if (mRootComp != null) {
-            mRootComp.onActivityCreate();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely,onActivityCreate can not be call!");
-        }
-
-        mGlobalEventReceiver = new WXGlobalEventReceiver(this);
-        getContext().registerReceiver(mGlobalEventReceiver, new IntentFilter(WXGlobalEventReceiver.EVENT_ACTION));
-
-
-    }
-
-    public boolean onCreateOptionsMenu(Menu menu) {
-        WXModuleManager.onCreateOptionsMenu(getInstanceId(), menu);
-        if (mRootComp != null) {
-            mRootComp.onCreateOptionsMenu(menu);
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely,onActivityStart can not be call!");
-        }
-        return true;
-    }
-
-
-
-    @Override
-    public void onActivityStart() {
-
-        // module listen Activity onActivityCreate
-        WXModuleManager.onActivityStart(getInstanceId());
-        if (mRootComp != null) {
-            mRootComp.onActivityStart();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely,onActivityStart can not be call!");
-        }
-        WXLogUtils.i("Application onActivityStart()");
-    }
-
-    private AtomicBoolean currentGround = new AtomicBoolean(false);
-    @Override
-    public void onActivityResume() {
-        // notify onActivityResume callback to module
-        WXModuleManager.onActivityResume(getInstanceId());
-
-        if (mRootComp != null) {
-            mRootComp.onActivityResume();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely, onActivityResume can not be call!");
-        }
-        WXLogUtils.i("Application onActivityResume()");
-        if (currentGround.get()) {
-            WXLogUtils.i("Application  to be in the foreground");
-            Intent intent = new Intent(WXGlobalEventReceiver.EVENT_ACTION);
-            intent.putExtra(WXGlobalEventReceiver.EVENT_NAME, Constants.Event.RESUME_EVENT);
-            intent.putExtra(WXGlobalEventReceiver.EVENT_WX_INSTANCEID, getInstanceId());
-            currentGround.set(false);
-            mContext.sendBroadcast(intent);
-        }
-        onViewAppear();
+  public void onCreateFinish() {
+    if (mContext != null) {
+      runOnUiThread(new Runnable() {
 
-        setViewPortWidth(mInstanceViewPortWidth);
-    }
-
-
-    @Override
-    public void onActivityPause() {
-        onViewDisappear();
-        if (!isCommit) {
-            Set<String> componentTypes = WXComponentFactory.getComponentTypesByInstanceId(getInstanceId());
-            if (componentTypes != null && componentTypes.contains(WXBasicComponentType.SCROLLER)) {
-                mWXPerformance.useScroller = 1;
+        @Override
+        public void run() {
+          if ( mContext != null) {
+            onViewAppear();
+            View wxView= mRenderContainer;
+            if(WXEnvironment.isApkDebugable() && WXSDKManager.getInstance().getIWXDebugAdapter()!=null){
+              wxView = WXSDKManager.getInstance().getIWXDebugAdapter().wrapContainer(WXSDKInstance.this,wxView);
             }
-            mWXPerformance.maxDeepViewLayer = getMaxDeepLayer();
-            if (mUserTrackAdapter != null) {
-                mUserTrackAdapter.commit(mContext, null, IWXUserTrackAdapter.LOAD, mWXPerformance, getUserTrackParams());
+            if(mRenderListener != null) {
+              mRenderListener.onViewCreated(WXSDKInstance.this, wxView);
             }
-            isCommit = true;
-        }
-        // module listen Activity onActivityPause
-        WXModuleManager.onActivityPause(getInstanceId());
-        if (mRootComp != null) {
-            mRootComp.onActivityPause();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely,onActivityPause can not be call!");
-        }
-        WXLogUtils.i("Application onActivityPause()");
-        if (!currentGround.get()) {
-            WXLogUtils.i("Application to be in the backround");
-            Intent intent = new Intent(WXGlobalEventReceiver.EVENT_ACTION);
-            intent.putExtra(WXGlobalEventReceiver.EVENT_NAME, Constants.Event.PAUSE_EVENT);
-            intent.putExtra(WXGlobalEventReceiver.EVENT_WX_INSTANCEID, getInstanceId());
-            mContext.sendBroadcast(intent);
-            this.currentGround.set(true);
-        }
-    }
-    @Override
-    public void onActivityStop() {
-
-        // notify onActivityResume callback to module
-        WXModuleManager.onActivityStop(getInstanceId());
-
-        if (mRootComp != null) {
-            mRootComp.onActivityStop();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely, onActivityStop can not be call!");
+            if (mStatisticsListener != null) {
+              mStatisticsListener.onFirstView();
+            }
+          }
         }
-        WXLogUtils.i("Application onActivityStop()");
-
+      });
     }
+  }
 
-    @Override
-    public void onActivityDestroy() {
-        WXModuleManager.onActivityDestroy(getInstanceId());
-
-        if (mRootComp != null) {
-            mRootComp.onActivityDestroy();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely, onActivityDestroy can not be call!");
-        }
+  /**
+   * call back when update finish
+   */
+  public void onUpdateFinish() {
+    WXLogUtils.d("Instance onUpdateSuccess");
+  }
 
-        destroy();
-    }
 
-    @Override
-    public boolean onActivityBack() {
+  public void runOnUiThread(Runnable action) {
+    WXSDKManager.getInstance().postOnUiThread(action, 0);
+  }
 
-        WXModuleManager.onActivityBack(getInstanceId());
+  public void onRenderSuccess(final int width, final int height) {
+    firstScreenRenderFinished();
 
-        if (mRootComp != null) {
-            return mRootComp.onActivityBack();
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely, onActivityBack can not be call!");
-        }
+    long time = System.currentTimeMillis() - mRenderStartTime;
+    WXLogUtils.renderPerformanceLog("onRenderSuccess", time);
+    WXLogUtils.renderPerformanceLog("   invokeCreateInstance",mWXPerformance.communicateTime);
+    WXLogUtils.renderPerformanceLog("   TotalCallNativeTime", mWXPerformance.callNativeTime);
+    WXLogUtils.renderPerformanceLog("       TotalJsonParseTime", mWXPerformance.parseJsonTime);
+    WXLogUtils.renderPerformanceLog("   TotalBatchTime", mWXPerformance.batchTime);
+    WXLogUtils.renderPerformanceLog("       TotalCssLayoutTime", mWXPerformance.cssLayoutTime);
+    WXLogUtils.renderPerformanceLog("       TotalApplyUpdateTime", mWXPerformance.applyUpdateTime);
+    WXLogUtils.renderPerformanceLog("       TotalUpdateDomObjTime", mWXPerformance.updateDomObjTime);
 
-        return false;
-    }
 
-    public boolean onBackPressed() {
-        WXComponent comp = getRootComponent();
-        if (comp != null) {
-            WXEvent events = comp.getDomObject().getEvents();
-            boolean hasBackPressed = events.contains(Constants.Event.CLICKBACKITEM);
-            if (hasBackPressed) {
-                WXBridgeManager.getInstance().fireEvent(this.mInstanceId, comp.getRef(), Constants.Event.CLICKBACKITEM, null, null);
-            }
-            return hasBackPressed;
-        }
-        return false;
+    mWXPerformance.totalTime = time;
+    if(mWXPerformance.screenRenderTime<0.001){
+      mWXPerformance.screenRenderTime =  time;
     }
-
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        WXModuleManager.onActivityResult(getInstanceId(), requestCode, resultCode, data);
-
-        if (mRootComp != null) {
-            mRootComp.onActivityResult(requestCode, resultCode, data);
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely, onActivityResult can not be call!");
-        }
+    mWXPerformance.componentCount = WXComponent.mComponentNum;
+    if(WXEnvironment.isApkDebugable()) {
+      WXLogUtils.d(WXLogUtils.WEEX_PERF_TAG, "mComponentNum:" + WXComponent.mComponentNum);
     }
+    WXComponent.mComponentNum = 0;
+    if (mRenderListener != null && mContext != null) {
+      runOnUiThread(new Runnable() {
 
-
-    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
-
-        WXModuleManager.onRequestPermissionsResult(getInstanceId(), requestCode, permissions, grantResults);
-
-        if (mRootComp != null) {
-            mRootComp.onRequestPermissionsResult(requestCode, permissions, grantResults);
-        } else {
-            WXLogUtils.w("Warning :Component tree has not build completely, onRequestPermissionsResult can not be call!");
-        }
-    }
-
-    /********************************
-     *  end hook Activity life cycle callback
-     ********************************************************/
-
-    public void onViewDisappear() {
-        WXComponent comp = getRootComponent();
-        if (comp != null) {
-            WXBridgeManager.getInstance().fireEvent(this.mInstanceId, comp.getRef(), Constants.Event.VIEWDISAPPEAR, null, null);
-            //call disappear of nested instances
-            for (OnInstanceVisibleListener instance : mVisibleListeners) {
-                instance.onDisappear();
+        @Override
+        public void run() {
+          if (mRenderListener != null && mContext != null) {
+            mRenderListener.onRenderSuccess(WXSDKInstance.this, width, height);
+            if (mUserTrackAdapter != null) {
+              WXPerformance performance=new WXPerformance();
+              performance.errCode=WXErrorCode.WX_SUCCESS.getErrorCode();
+              performance.args=getBundleUrl();
+              mUserTrackAdapter.commit(mContext,null,IWXUserTrackAdapter.JS_BRIDGE,performance,getUserTrackParams());
             }
-        }
-    }
-
-    public void onViewAppear() {
-        WXComponent comp = getRootComponent();
-        if (comp != null) {
-            WXBridgeManager.getInstance().fireEvent(this.mInstanceId, comp.getRef(), Constants.Event.VIEWAPPEAR, null, null);
-            for (OnInstanceVisibleListener instance : mVisibleListeners) {
-                instance.onAppear();
+            if (WXEnvironment.isApkDebugable()) {
+              WXLogUtils.d(WXLogUtils.WEEX_PERF_TAG, mWXPerformance.toString());
             }
+          }
         }
+      });
     }
-
-
-    public void onCreateFinish() {
-        if (mContext != null) {
-            runOnUiThread(new Runnable() {
-
-                @Override
-                public void run() {
-                    if (mContext != null) {
-                        onViewAppear();
-                        View wxView = mRenderContainer;
-                        if (WXEnvironment.isApkDebugable() && WXSDKManager.getInstance().getIWXDebugAdapter() != null) {
-                            wxView = WXSDKManager.getInstance().getIWXDebugAdapter().wrapContainer(WXSDKInstance.this, wxView);
-                        }
-                        if (mRenderListener != null) {
-                            mRenderListener.onViewCreated(WXSDKInstance.this, wxView);
-                        }
-                        if (mStatisticsListener != null) {
-                            mStatisticsListener.onFirstView();
-                        }
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * call back when update finish
-     */
-    public void onUpdateFinish() {
-        WXLogUtils.d("Instance onUpdateSuccess");
-    }
-
-
-    public void runOnUiThread(Runnable action) {
-        WXSDKManager.getInstance().postOnUiThread(action, 0);
+    if(!WXEnvironment.isApkDebugable()){
+      Log.e("weex_perf",mWXPerformance.getPerfData());
     }
+  }
 
-    public void onRenderSuccess(final int width, final int height) {
-        firstScreenRenderFinished();
-
-        long time = System.currentTimeMillis() - mRenderStartTime;
-        WXLogUtils.renderPerformanceLog("onRenderSuccess", time);
-        WXLogUtils.renderPerformanceLog("   invokeCreateInstance", mWXPerformance.communicateTime);
-        WXLogUtils.renderPerformanceLog("   TotalCallNativeTime", mWXPerformance.callNativeTime);
-        WXLogUtils.renderPerformanceLog("       TotalJsonParseTime", mWXPerformance.parseJsonTime);
-        WXLogUtils.renderPerformanceLog("   TotalBatchTime", mWXPerformance.batchTime);
-        WXLogUtils.renderPerformanceLog("       TotalCssLayoutTime", mWXPerformance.cssLayoutTime);
-        WXLogUtils.renderPerformanceLog("       TotalApplyUpdateTime", mWXPerformance.applyUpdateTime);
-        WXLogUtils.renderPerformanceLog("       TotalUpdateDomObjTime", mWXPerformance.updateDomObjTime);
-
-
-        mWXPerformance.totalTime = time;
-        if (mWXPerformance.screenRenderTime < 0.001) {
-            mWXPerformance.screenRenderTime = time;
-        }
-        mWXPerformance.componentCount = WXComponent.mComponentNum;
-        if (WXEnvironment.isApkDebugable()) {
-            WXLogUtils.d(WXLogUtils.WEEX_PERF_TAG, "mComponentNum:" + WXComponent.mComponentNum);
-        }
-        WXComponent.mComponentNum = 0;
-        if (mRenderListener != null && mContext != null) {
-            runOnUiThread(new Runnable() {
-
-                @Override
-                public void run() {
-                    if (mRenderListener != null && mContext != null) {
-                        mRenderListener.onRenderSuccess(WXSDKInstance.this, width, height);
-                        if (mUserTrackAdapter != null) {
-                            WXPerformance performance = new WXPerformance();
-                            performance.errCode = WXErrorCode.WX_SUCCESS.getErrorCode();
-                            performance.args = getBundleUrl();
-                            mUserTrackAdapter.commit(mContext, null, IWXUserTrackAdapter.JS_BRIDGE, performance, getUserTrackParams());
-                        }
-                        if (WXEnvironment.isApkDebugable()) {
-                            WXLogUtils.d(WXLogUtils.WEEX_PERF_TAG, mWXPerformance.toString());
-                        }
-                    }
-                }
-            });
-        }
-        if (!WXEnvironment.isApkDebugable()) {
-            Log.e("weex_perf", mWXPerformance.getPerfData());
-        }
-    }
-
-    public void onRefreshSuccess(final int width, final int height) {
-        WXLogUtils.renderPerformanceLog("onRefreshSuccess", (System.currentTimeMillis() - mRefreshStartTime));
-        if (mRenderListener != null && mContext != null) {
-            runOnUiThread(new Runnable() {
-
-                @Override
-                public void run() {
-                    if (mRenderListener != null && mContext != null) {
-                        mRenderListener.onRefreshSuccess(WXSDKInstance.this, width, height);
-                    }
-                }
-            });
-        }
-    }
-
-    public void onRenderError(final String errCode, final String msg) {
-        if (mRenderListener != null && mContext != null) {
-            runOnUiThread(new Runnable() {
-
-                @Override
-                public void run() {
-                    if (mRenderListener != null && mContext != null) {
-                        mRenderListener.onException(WXSDKInstance.this, errCode, msg);
-                    }
-                }
-            });
-        }
-    }
-
-    public void onJSException(final String errCode, final String function, final String exception) {
-        if (mRenderListener != null && mContext != null) {
-            runOnUiThread(new Runnable() {
-
-                @Override
-                public void run() {
-                    if (mRenderListener != null && mContext != null) {
-                        StringBuilder builder = new StringBuilder();
-                        builder.append(function);
-                        builder.append(exception);
-                        mRenderListener.onException(WXSDKInstance.this, errCode, builder.toString());
-                    }
-                }
-            });
-        }
-    }
-
-
-    @Override
-    public final void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int
-            oldTop, int oldRight, int oldBottom) {
-        if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
-            onLayoutChange(v);
-        }
-    }
+  public void onRefreshSuccess(final int width, final int height) {
+    WXLogUtils.renderPerformanceLog("onRefreshSuccess", (System.currentTimeMillis() - mRefreshStartTime));
+    if (mRenderListener != null && mContext != null) {
+      runOnUiThread(new Runnable() {
 
-    /**
-     * Subclass should override this method to get notifications of layout change of GodView.
-     *
-     * @param godView the godView.
-     */
-    public void onLayoutChange(View godView) {
-
-    }
-
-    private boolean mCreateInstance = true;
-
-    public void firstScreenCreateInstanceTime(long time) {
-        if (mCreateInstance) {
-            mWXPerformance.firstScreenJSFExecuteTime = time - mRenderStartTime;
-            mCreateInstance = false;
-        }
-    }
-
-    public void callNativeTime(long time) {
-        mWXPerformance.callNativeTime += time;
-    }
-
-    public void jsonParseTime(long time) {
-        mWXPerformance.parseJsonTime += time;
-    }
-
-    public void firstScreenRenderFinished() {
-        if (mEnd == true)
-            return;
-
-        mEnd = true;
-
-        if (mStatisticsListener != null && mContext != null) {
-            runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    if (mStatisticsListener != null && mContext != null) {
-                        Trace.beginSection("onFirstScreen");
-                        mStatisticsListener.onFirstScreen();
-                        Trace.endSection();
-                    }
-                }
-            });
-        }
-
-        mWXPerformance.screenRenderTime = System.currentTimeMillis() - mRenderStartTime;
-        WXLogUtils.renderPerformanceLog("firstScreenRenderFinished", mWXPerformance.screenRenderTime);
-        WXLogUtils.renderPerformanceLog("   firstScreenJSFExecuteTime", mWXPerformance.firstScreenJSFExecuteTime);
-        WXLogUtils.renderPerformanceLog("   firstScreenCallNativeTime", mWXPerformance.callNativeTime);
-        WXLogUtils.renderPerformanceLog("       firstScreenJsonParseTime", mWXPerformance.parseJsonTime);
-        WXLogUtils.renderPerformanceLog("   firstScreenBatchTime", mWXPerformance.batchTime);
-        WXLogUtils.renderPerformanceLog("       firstScreenCssLayoutTime", mWXPerformance.cssLayoutTime);
-        WXLogUtils.renderPerformanceLog("       firstScreenApplyUpdateTime", mWXPerformance.applyUpdateTime);
-        WXLogUtils.renderPerformanceLog("       firstScreenUpdateDomObjTime", mWXPerformance.updateDomObjTime);
-    }
-
-    public void batchTime(long time) {
-        mWXPerformance.batchTime += time;
-    }
-
-    public void cssLayoutTime(long time) {
-        mWXPerformance.cssLayoutTime += time;
-    }
-
-    public void applyUpdateTime(long time) {
-        mWXPerformance.applyUpdateTime += time;
-    }
-
-    public void updateDomObjTime(long time) {
-        mWXPerformance.updateDomObjTime += time;
-    }
-
-
-    public void createInstanceFinished(long time) {
-        if (time > 0) {
-            mWXPerformance.communicateTime = time;
-        }
-    }
-
-    /**
-     * UserTrack Log
-     */
-    public void commitUTStab(final String type, final WXErrorCode errorCode) {
-        if (TextUtils.isEmpty(type) || errorCode == null) {
-            return;
+        @Override
+        public void run() {
+          if (mRenderListener != null && mContext != null) {
+            mRenderListener.onRefreshSuccess(WXSDKInstance.this, width, height);
+          }
         }
-
-        runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                // Record exception if a render error happened.
-                if (mStatisticsListener != null && errorCode != WXErrorCode.WX_SUCCESS) {
-                    mStatisticsListener.onException(mInstanceId,
-                            errorCode.getErrorCode(),
-                            errorCode.getErrorMsg());
-                }
-
-                WXPerformance performance = new WXPerformance();
-                performance.errCode = errorCode.getErrorCode();
-                performance.args = errorCode.getArgs();
-                if (errorCode != WXErrorCode.WX_SUCCESS) {
-                    performance.errMsg = errorCode.getErrorMsg();
-                    if (WXEnvironment.isApkDebugable()) {
-                        WXLogUtils.d(performance.toString());
-                    }
-                }
-                if (mUserTrackAdapter != null) {
-                    mUserTrackAdapter.commit(mContext, null, type, performance, getUserTrackParams());
-                }
-            }
-        });
+      });
     }
+  }
 
-    private void destroyView(View rootView) {
-        try {
-            if (rootView instanceof ViewGroup) {
-                ViewGroup cViewGroup = ((ViewGroup) rootView);
-                for (int index = 0; index < cViewGroup.getChildCount(); index++) {
-                    destroyView(cViewGroup.getChildAt(index));
-                }
+  public void onRenderError(final String errCode, final String msg) {
+    if (mRenderListener != null && mContext != null) {
+      runOnUiThread(new Runnable() {
 
-                cViewGroup.removeViews(0, ((ViewGroup) rootView).getChildCount());
-                // Ensure that the viewgroup's status to be normal
-                WXReflectionUtils.setValue(rootView, "mChildrenCount", 0);
-
-            }
-            if (rootView instanceof Destroyable) {
-                ((Destroyable) rootView).destroy();
-            }
-        } catch (Exception e) {
-            WXLogUtils.e("WXSDKInstance destroyView Exception: ", e);
+        @Override
+        public void run() {
+          if (mRenderListener != null && mContext != null) {
+            mRenderListener.onException(WXSDKInstance.this, errCode, msg);
+          }
         }
+      });
     }
+  }
 
-    public synchronized void destroy() {
-        WXSDKManager.getInstance().destroyInstance(mInstanceId);
-        WXComponentFactory.removeComponentTypesByInstanceId(getInstanceId());
-
-        if (mGlobalEventReceiver != null) {
-            getContext().unregisterReceiver(mGlobalEventReceiver);
-            mGlobalEventReceiver = null;
-        }
-        if (mRootComp != null) {
-            mRootComp.destroy();
-            destroyView(mRenderContainer);
-            mRenderContainer = null;
-            mRootComp = null;
-        }
+  public void onJSException(final String errCode, final String function, final String exception) {
+    if (mRenderListener != null && mContext != null) {
+      runOnUiThread(new Runnable() {
 
-        if (mGlobalEvents != null) {
-            mGlobalEvents.clear();
+        @Override
+        public void run() {
+          if (mRenderListener != null && mContext != null) {
+            StringBuilder builder = new StringBuilder();
+            builder.append(function);
+            builder.append(exception);
+            mRenderListener.onException(WXSDKInstance.this, errCode, builder.toString());
+          }
         }
-
-
-        mNestedInstanceInterceptor = null;
-        mUserTrackAdapter = null;
-        mScrollView = null;
-        mContext = null;
-        mRenderListener = null;
-        isDestroy = true;
-        mStatisticsListener = null;
+      });
     }
+  }
 
-    public boolean isDestroy() {
-        return isDestroy;
-    }
 
-    /**
-     * @return If you use render () the return value may be empty
-     */
-    public
-    @Nullable
-    String getBundleUrl() {
-        return mBundleUrl;
+  @Override
+  public final void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int
+      oldTop, int oldRight, int oldBottom) {
+    if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
+      onLayoutChange(v);
     }
+  }
 
-    public View getRootView() {
-        return mRootComp.getRealView();
-    }
+  /**
+   * Subclass should override this method to get notifications of layout change of GodView.
+   * @param godView the godView.
+   */
+  public void onLayoutChange(View godView) {
 
-    public View getContainerView() {
-        return mRenderContainer;
-    }
+  }
 
-    @Deprecated
-    public void setBundleUrl(String url) {
-        mBundleUrl = url;
-        if (WXSDKManager.getInstance().getValidateProcessor() != null) {
-            mNeedValidate = WXSDKManager.getInstance().getValidateProcessor().needValidate(mBundleUrl);
-        }
+  private boolean mCreateInstance =true;
+  public void firstScreenCreateInstanceTime(long time) {
+    if(mCreateInstance) {
+      mWXPerformance.firstScreenJSFExecuteTime = time -mRenderStartTime;
+      mCreateInstance =false;
     }
+  }
 
-    public void onRootCreated(WXComponent root) {
-        this.mRootComp = root;
-        mRenderContainer.addView(root.getHostView());
-        setSize(mRenderContainer.getWidth(), mRenderContainer.getHeight());
-    }
-
-    /**
-     * Move fixed view to container ,except it's already moved.
-     *
-     * @param fixedChild
-     */
-    public void moveFixedView(View fixedChild) {
-        if (mRenderContainer != null) {
-            ViewGroup parent;
-            if ((parent = (ViewGroup) fixedChild.getParent()) != null) {
-                if (parent != mRenderContainer) {
-                    parent.removeView(fixedChild);
-                    mRenderContainer.addView(fixedChild);
-                }
-            } else {
-                mRenderContainer.addView(fixedChild);
-            }
-        }
-    }
+  public void callNativeTime(long time) {
+    mWXPerformance.callNativeTime += time;
+  }
 
-    public void removeFixedView(View fixedChild) {
-        if (mRenderContainer != null) {
-            mRenderContainer.removeView(fixedChild);
-        }
-    }
+  public void jsonParseTime(long time) {
+    mWXPerformance.parseJsonTime += time;
+  }
 
-    public synchronized List<OnWXScrollListener> getWXScrollListeners() {
-        return mWXScrollListeners;
-    }
+  public void firstScreenRenderFinished() {
+    if(mEnd == true)
+       return;
 
-    public synchronized void registerOnWXScrollListener(OnWXScrollListener wxScrollListener) {
-        if (mWXScrollListeners == null) {
-            mWXScrollListeners = new ArrayList<>();
-        }
-        mWXScrollListeners.add(wxScrollListener);
-    }
+    mEnd = true;
 
-    private void updateRootComponentStyle(JSONObject style) {
-        Message message = Message.obtain();
-        WXDomTask task = new WXDomTask();
-        task.instanceId = getInstanceId();
-        if (task.args == null) {
-            task.args = new ArrayList<>();
-        }
-        task.args.add(WXDomObject.ROOT);
-        task.args.add(style);
-        message.obj = task;
-        message.what = WXDomHandler.MsgType.WX_DOM_UPDATE_STYLE;
-        WXSDKManager.getInstance().getWXDomManager().sendMessage(message);
-    }
+    if (mStatisticsListener != null && mContext != null) {
+      runOnUiThread(new Runnable() {
+        @Override
+        public void run() {
+          if (mStatisticsListener != null && mContext != null) {
+            Trace.beginSection("onFirstScreen");
+            mStatisticsListener.onFirstScreen();
+            Trace.endSection();
+          }
+        }
+      });
+    }
+
+    mWXPerformance.screenRenderTime = System.currentTimeMillis() - mRenderStartTime;
+    WXLogUtils.renderPerformanceLog("firstScreenRenderFinished", mWXPerformance.screenRenderTime);
+    WXLogUtils.renderPerformanceLog("   firstScreenJSFExecuteTime", mWXPerformance.firstScreenJSFExecuteTime);
+    WXLogUtils.renderPerformanceLog("   firstScreenCallNativeTime", mWXPerformance.callNativeTime);
+    WXLogUtils.renderPerformanceLog("       firstScreenJsonParseTime", mWXPerformance.parseJsonTime);
+    WXLogUtils.renderPerformanceLog("   firstScreenBatchTime", mWXPerformance.batchTime);
+    WXLogUtils.renderPerformanceLog("       firstScreenCssLayoutTime", mWXPerformance.cssLayoutTime);
+    WXLogUtils.renderPerformanceLog("       firstScreenApplyUpdateTime", mWXPerformance.applyUpdateTime);
+    WXLogUtils.renderPerformanceLog("       firstScreenUpdateDomObjTime", mWXPerformance.updateDomObjTime);
+  }
 
-    public void setSize(int width, int height) {
-        if (width < 0 || height < 0 || isDestroy || !mRendered) {
-            return;
-        }
-        float realWidth = WXViewUtils.getWebPxByWidth(width, getInstanceViewPortWidth());
-        float realHeight = WXViewUtils.getWebPxByWidth(height, getInstanceViewPortWidth());
-
-        View godView = mRenderContainer;
-        if (godView != null) {
-            ViewGroup.LayoutParams layoutParams = godView.getLayoutParams();
-            if (layoutParams != null) {
-                if (godView.getWidth() != width || godView.getHeight() != height) {
-                    layoutParams.width = width;
-                    layoutParams.height = height;
-                    godView.setLayoutParams(layoutParams);
-                }
-
-                JSONObject style = new JSONObject();
-                WXComponent rootComponent = mRootComp;
-
-                if (rootComponent == null) {
-                    return;
-                }
-                style.put(Constants.Name.DEFAULT_WIDTH, realWidth);
-                style.put(Constants.Name.DEFAULT_HEIGHT, realHeight);
-                updateRootComponentStyle(style);
-            }
-        }
+  public void batchTime(long time) {
+    mWXPerformance.batchTime += time;
+  }
+  public void cssLayoutTime(long time) {
+      mWXPerformance.cssLayoutTime += time;
+  }
+
+  public void applyUpdateTime(long time) {
+      mWXPerformance.applyUpdateTime += time;
+  }
+
+  public void updateDomObjTime(long time) {
+      mWXPerformance.updateDomObjTime += time;
+    }
+
+
+  public void createInstanceFinished(long time) {
+    if (time > 0) {
+      mWXPerformance.communicateTime = time;
+    }
+  }
+
+  /**
+   * UserTrack Log
+   */
+  public void commitUTStab(final String type, final WXErrorCode errorCode) {
+    if (TextUtils.isEmpty(type) || errorCode == null) {
+      return;
+    }
+
+    runOnUiThread(new Runnable() {
+      @Override
+      public void run() {
+        // Record exception if a render error happened.
+        if (mStatisticsListener != null && errorCode != WXErrorCode.WX_SUCCESS) {
+          mStatisticsListener.onException(mInstanceId,
+                                          errorCode.getErrorCode(),
+                                          errorCode.getErrorMsg());
+        }
+
+        WXPerformance performance = new WXPerformance();
+        performance.errCode = errorCode.getErrorCode();
+        performance.args = errorCode.getArgs();
+        if (errorCode != WXErrorCode.WX_SUCCESS) {
+          performance.errMsg = errorCode.getErrorMsg();
+          if (WXEnvironment.isApkDebugable()) {
+            WXLogUtils.d(performance.toString());
+          }
+        }
+        if( mUserTrackAdapter!= null) {
+          mUserTrackAdapter.commit(mContext, null, type, performance, getUserTrackParams());
+        }
+      }
+    });
+  }
+
+  private void destroyView(View rootView) {
+    try {
+      if (rootView instanceof ViewGroup) {
+        ViewGroup cViewGroup = ((ViewGroup) rootView);
+        for (int index = 0; index < cViewGroup.getChildCount(); index++) {
+          destroyView(cViewGroup.getChildAt(index));
+        }
+
+        cViewGroup.removeViews(0, ((ViewGroup) rootView).getChildCount());
+        // Ensure that the viewgroup's status to be normal
+        WXReflectionUtils.setValue(rootView, "mChildrenCount", 0);
+
+      }
+      if(rootView instanceof Destroyable){
+        ((Destroyable)rootView).destroy();
+      }
+    } catch (Exception e) {
+      WXLogUtils.e("WXSDKInstance destroyView Exception: ", e);
+    }
+  }
+
+  public synchronized void destroy() {
+    WXSDKManager.getInstance().destroyInstance(mInstanceId);
+    WXComponentFactory.removeComponentTypesByInstanceId(getInstanceId());
+
+    if(mGlobalEventReceiver!=null){
+      getContext().unregisterReceiver(mGlobalEventReceiver);
+      mGlobalEventReceiver=null;
+    }
+    if(mRootComp != null ) {
+      mRootComp.destroy();
+      destroyView(mRenderContainer);
+      mRenderContainer = null;
+      mRootComp = null;
+    }
+
+    if(mGlobalEvents!=null){
+      mGlobalEvents.clear();
+    }
+
+
+    mNestedInstanceInterceptor = null;
+    mUserTrackAdapter = null;
+    mScrollView = null;
+    mContext = null;
+    mRenderListener = null;
+    isDestroy = true;
+    mStatisticsListener = null;
+  }
+
+  public boolean isDestroy(){
+    return isDestroy;
+  }
+
+  /**
+   * @return If you use render () the return value may be empty
+   */
+  public @Nullable String getBundleUrl() {
+    return mBundleUrl;
+  }
+
+  public View getRootView() {
+    return mRootComp.getRealView();
+  }
+
+  public View getContainerView() {
+    return mRenderContainer;
+  }
+
+  @Deprecated
+  public void setBundleUrl(String url){
+    mBundleUrl = url;
+    if(WXSDKManager.getInstance().getValidateProcessor()!=null) {
+      mNeedValidate = WXSDKManager.getInstance().getValidateProcessor().needValidate(mBundleUrl);
+    }
+  }
+
+  public void onRootCreated(WXComponent root) {
+    this.mRootComp = root;
+    mRenderContainer.addView(root.getHostView());
+    setSize(mRenderContainer.getWidth(),mRenderContainer.getHeight());
+  }
+
+  /**
+   * Move fixed view to container ,except it's already moved.
+   * @param fixedChild
+   */
+  public void moveFixedView(View fixedChild){
+    if(mRenderContainer != null) {
+      ViewGroup parent;
+      if((parent = (ViewGroup) fixedChild.getParent()) != null){
+        if (parent != mRenderContainer) {
+          parent.removeView(fixedChild);
+          mRenderContainer.addView(fixedChild);
+        }
+      }else{
+        mRenderContainer.addView(fixedChild);
+      }
+    }
+  }
+
+  public void removeFixedView(View fixedChild){
+    if(mRenderContainer != null) {
+      mRenderContainer.removeView(fixedChild);
+    }
+  }
+
+  public synchronized List<OnWXScrollListener> getWXScrollListeners() {
+    return mWXScrollListeners;
+  }
+
+  public synchronized void registerOnWXScrollListener(OnWXScrollListener wxScrollListener) {
+    if(mWXScrollListeners==null){
+      mWXScrollListeners=new ArrayList<>();
+    }
+    mWXScrollListeners.add(wxScrollListener);
+  }
+
+  private void updateRootComponentStyle(JSONObject style) {
+    Message message = Message.obtain();
+    WXDomTask task = new WXDomTask();
+    task.instanceId = getInstanceId();
+    if (task.args == null) {
+      task.args = new ArrayList<>();
+    }
+    task.args.add(WXDomObject.ROOT);
+    task.args.add(style);
+    message.obj = task;
+    message.what = WXDomHandler.MsgType.WX_DOM_UPDATE_STYLE;
+    WXSDKManager.getInstance().getWXDomManager().sendMessage(message);
+  }
+
+  public void setSize(int width, int height) {
+    if (width < 0 || height < 0 || isDestroy || !mRendered) {
+      return;
+    }
+    float realWidth = WXViewUtils.getWebPxByWidth(width,getInstanceViewPortWidth());
+    float realHeight = WXViewUtils.getWebPxByWidth(height,getInstanceViewPortWidth());
+
+    View godView = mRenderContainer;
+    if (godView != null) {
+      ViewGroup.LayoutParams layoutParams = godView.getLayoutParams();
+      if (layoutParams != null) {
+        if(godView.getWidth() != width || godView.getHeight() != height) {
+          layoutParams.width = width;
+          layoutParams.height = height;
+          godView.setLayoutParams(layoutParams);
+        }
+
+        JSONObject style = new JSONObject();
+        WXComponent rootComponent = mRootComp;
+
+        if(rootComponent == null){
+          return;
+        }
+        style.put(Constants.Name.DEFAULT_WIDTH, realWidth);
+        style.put(Constants.Name.DEFAULT_HEIGHT, realHeight);
+        updateRootComponentStyle(style);
+      }
+    }
+  }
+
+  /*Global Event*/
+  private HashMap<String, List<String>> mGlobalEvents = new HashMap<>();
+
+  public void fireGlobalEventCallback(String eventName, Map<String,Object> params){
+    List<String> callbacks=mGlobalEvents.get(eventName);
+    if(callbacks!=null){
+      for(String callback:callbacks){
+        WXSDKManager.getInstance().callback(mInstanceId,callback,params,true);
+      }
+    }
+  }
+
+  /**
+   * Fire event callback on a element.
+   * @param elementRef
+   * @param type
+   * @param data
+   * @param domChanges
+   */
+  public void fireEvent(String elementRef,final String type, final Map<String, Object> data,final Map<String, Object> domChanges){
+    WXBridgeManager.getInstance().fireEventOnNode(getInstanceId(),elementRef,type,data,domChanges);
+  }
+
+  public void fireEvent(String elementRef,final String type, final Map<String, Object> data){
+    fireEvent(elementRef,type,data,null);
+  }
+
+  public void fireEvent(String ref, String type){
+    fireEvent(ref,type,new HashMap<String, Object>());
+  }
+
+  protected void addEventListener(String eventName, String callback) {
+    if (TextUtils.isEmpty(eventName) || TextUtils.isEmpty(callback)) {
+      return;
+    }
+    List<String> callbacks = mGlobalEvents.get(eventName);
+    if (callbacks == null) {
+      callbacks = new ArrayList<>();
+      mGlobalEvents.put(eventName, callbacks);
+    }
+    callbacks.add(callback);
+  }
+  protected void removeEventListener(String eventName, String callback) {
+    if (TextUtils.isEmpty(eventName) || TextUtils.isEmpty(callback)) {
+      return;
+    }
+    List<String> callbacks = mGlobalEvents.get(eventName);
+    if (callbacks != null) {
+      callbacks.remove(callback);
+    }
+  }
+
+  protected void removeEventListener(String eventName) {
+    if (TextUtils.isEmpty(eventName)) {
+      return;
+    }
+    mGlobalEvents.remove(eventName);
+  }
+
+  /**
+   * Notifies WEEX that this event has occurred
+   * @param eventName WEEX register event
+   * @param module Events occur in this Module
+   * @param params The parameters to be notified to WEEX are required
+   */
+  public void fireModuleEvent(String eventName, WXModule module,Map<String, Object> params) {
+    if (TextUtils.isEmpty(eventName) || module == null) {
+      return;
+    }
+
+    Map<String, Object> event = new HashMap<>();
+    event.put("type", eventName);
+    event.put("module", module.getModuleName());
+    event.put("data", params);
+
+    List<String> callbacks = module.getEventCallbacks(eventName);
+    if (callbacks != null) {
+      for (String callback : callbacks) {
+        SimpleJSCallback jsCallback = new SimpleJSCallback(mInstanceId, callback);
+        if (module.isOnce(callback)) {
+          jsCallback.invoke(event);
+        } else {
+          jsCallback.invokeAndKeepAlive(event);
+        }
+      }
+    }
+  }
+
+  /**
+   * Check whether the current module registered the event
+   * @param eventName EventName register in weex
+   * @param module Events occur in this Module
+   * @return  register->true
+   */
+  public boolean checkModuleEventRegistered(String eventName,WXModule module) {
+    if (module != null) {
+      List<String> events = module.getEventCallbacks(eventName);
+      if (events != null && events.size() > 0) {
+        return true;
+      }
     }
+    return false;
+  }
 
-    /*Global Event*/
-    private HashMap<String, List<String>> mGlobalEvents = new HashMap<>();
+  public WXPerformance getWXPerformance(){
+    return mWXPerformance;
+  }
 
-    public void fireGlobalEventCallback(String eventName, Map<String, Object> params) {
-        List<String> callbacks = mGlobalEvents.get(eventName);
-        if (callbacks != null) {
-            for (String callback : callbacks) {
-                WXSDKManager.getInstance().callback(mInstanceId, callback, params, true);
-            }
-        }
-    }
+  public Map<String, Serializable> getUserTrackParams() {
+    return mUserTrackParams;
+  }
 
-    /**
-     * Fire event callback on a element.
-     *
-     * @param elementRef
-     * @param type
-     * @param data
-     * @param domChanges
-     */
-    public void fireEvent(String elementRef, final String type, final Map<String, Object> data, final Map<String, Object> domChanges) {
-        WXBridgeManager.getInstance().fireEventOnNode(getInstanceId(), elementRef,

<TRUNCATED>