Merge heron into master (#2636)

diff --git a/build.gradle b/build.gradle
index f22e07a..30fe1ad 100755
--- a/build.gradle
+++ b/build.gradle
@@ -93,6 +93,7 @@
 
     implementation project(':commons')
     implementation project(':weex_sdk')
+ //   implementation project(':HeronAndroid')
     //https://github.com/weexteam/weex-analyzer-android
     //Weex-Analyzer provides several convenient tools such as Memory Monitor
     // to optimize your application. It's not available by default,you can
diff --git a/src/main/assets/videoplus.js b/src/main/assets/videoplus.js
new file mode 100644
index 0000000..69e30af
--- /dev/null
+++ b/src/main/assets/videoplus.js
@@ -0,0 +1,298 @@
+// { "framework": "Vue" }
+"use weex:vue";
+
+/******/
+(function(modules) { // webpackBootstrap
+    /******/ // The module cache
+    /******/
+    var installedModules = {};
+    /******/
+    /******/ // The require function
+    /******/
+    function __webpack_require__(moduleId) {
+        /******/
+        /******/ // Check if module is in cache
+        /******/
+        if (installedModules[moduleId]) {
+            /******/
+            return installedModules[moduleId].exports;
+            /******/
+        }
+        /******/ // Create a new module (and put it into the cache)
+        /******/
+        var module = installedModules[moduleId] = {
+            /******/
+            i: moduleId,
+            /******/
+            l: false,
+            /******/
+            exports: {}
+            /******/
+        };
+        /******/
+        /******/ // Execute the module function
+        /******/
+        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+        /******/
+        /******/ // Flag the module as loaded
+        /******/
+        module.l = true;
+        /******/
+        /******/ // Return the exports of the module
+        /******/
+        return module.exports;
+        /******/
+    }
+    /******/
+    /******/
+    /******/ // expose the modules object (__webpack_modules__)
+    /******/
+    __webpack_require__.m = modules;
+    /******/
+    /******/ // expose the module cache
+    /******/
+    __webpack_require__.c = installedModules;
+    /******/
+    /******/ // define getter function for harmony exports
+    /******/
+    __webpack_require__.d = function(exports, name, getter) {
+        /******/
+        if (!__webpack_require__.o(exports, name)) {
+            /******/
+            Object.defineProperty(exports, name, {
+                /******/
+                configurable: false,
+                /******/
+                enumerable: true,
+                /******/
+                get: getter
+                    /******/
+            });
+            /******/
+        }
+        /******/
+    };
+    /******/
+    /******/ // getDefaultExport function for compatibility with non-harmony modules
+    /******/
+    __webpack_require__.n = function(module) {
+        /******/
+        var getter = module && module.__esModule ?
+            /******/
+            function getDefault() {
+                return module['default'];
+            } :
+            /******/
+            function getModuleExports() {
+                return module;
+            };
+        /******/
+        __webpack_require__.d(getter, 'a', getter);
+        /******/
+        return getter;
+        /******/
+    };
+    /******/
+    /******/ // Object.prototype.hasOwnProperty.call
+    /******/
+    __webpack_require__.o = function(object, property) {
+        return Object.prototype.hasOwnProperty.call(object, property);
+    };
+    /******/
+    /******/ // __webpack_public_path__
+    /******/
+    __webpack_require__.p = "";
+    /******/
+    /******/ // Load entry module and return exports
+    /******/
+    return __webpack_require__(__webpack_require__.s = 0);
+    /******/
+})
+/************************************************************************/
+/******/
+([
+    /* 0 */
+    /***/
+    (function(module, exports, __webpack_require__) {
+
+        "use strict";
+
+
+        var _App = __webpack_require__(1);
+
+        var _App2 = _interopRequireDefault(_App);
+
+        function _interopRequireDefault(obj) {
+            return obj && obj.__esModule ? obj : {
+                default: obj
+            };
+        }
+
+        _App2.default.el = '#root';
+        new Vue(_App2.default);
+
+        /***/
+    }),
+    /* 1 */
+    /***/
+    (function(module, exports, __webpack_require__) {
+
+        var __vue_exports__, __vue_options__
+        var __vue_styles__ = []
+
+        /* styles */
+        __vue_styles__.push(__webpack_require__(2))
+
+        /* script */
+        __vue_exports__ = __webpack_require__(3)
+
+        /* template */
+        var __vue_template__ = __webpack_require__(4)
+        __vue_options__ = __vue_exports__ = __vue_exports__ || {}
+        if (
+            typeof __vue_exports__.default === "object" ||
+            typeof __vue_exports__.default === "function"
+        ) {
+            if (Object.keys(__vue_exports__).some(function(key) {
+                    return key !== "default" && key !== "__esModule"
+                })) {
+                console.error("named exports are not supported in *.vue files.")
+            }
+            __vue_options__ = __vue_exports__ = __vue_exports__.default
+        }
+        if (typeof __vue_options__ === "function") {
+            __vue_options__ = __vue_options__.options
+        }
+        __vue_options__.__file = "/usr/src/app/raw/072b3765e21f00b469b67c324c6e3dde/App.vue"
+        __vue_options__.render = __vue_template__.render
+        __vue_options__.staticRenderFns = __vue_template__.staticRenderFns
+        __vue_options__._scopeId = "data-v-f7ea0eb2"
+        __vue_options__.style = __vue_options__.style || {}
+        __vue_styles__.forEach(function(module) {
+            for (var name in module) {
+                __vue_options__.style[name] = module[name]
+            }
+        })
+        if (typeof __register_static_styles__ === "function") {
+            __register_static_styles__(__vue_options__._scopeId, __vue_styles__)
+        }
+
+        module.exports = __vue_exports__
+
+
+        /***/
+    }),
+    /* 2 */
+    /***/
+    (function(module, exports) {
+
+        module.exports = {
+            "video": {
+                "width": "630",
+                "height": "350",
+                "marginTop": "60",
+                "marginLeft": "60",
+                "backgroundColor":"red"
+            },
+            "info": {
+                "marginTop": "40",
+                "fontSize": "40",
+                "textAlign": "center"
+            }
+        }
+
+        /***/
+    }),
+    /* 3 */
+    /***/
+    (function(module, exports, __webpack_require__) {
+
+        "use strict";
+
+
+        Object.defineProperty(exports, "__esModule", {
+            value: true
+        });
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+        //
+
+        exports.default = {
+            data: function data() {
+                return {
+                    state: '----',
+                    src: 'http://flv2.bn.netease.com/videolib3/1611/01/XGqSL5981/SD/XGqSL5981-mobile.mp4'
+                };
+            },
+
+            methods: {
+                onstart: function onstart(event) {
+                    this.state = 'onstart';
+                },
+                onpause: function onpause(event) {
+                    this.state = 'onpause';
+                },
+                onfinish: function onfinish(event) {
+                    this.state = 'onfinish';
+                },
+                onfail: function onfail(event) {
+                    this.state = 'onfinish';
+                }
+            }
+        };
+
+        /***/
+    }),
+    /* 4 */
+    /***/
+    (function(module, exports) {
+
+        module.exports = {
+            render: function() {
+                var _vm = this;
+                var _h = _vm.$createElement;
+                var _c = _vm._self._c || _h;
+                return _c('div', [_c('videoplus', {
+                    staticClass: ["video"],
+                    attrs: {
+                        "src": _vm.src,
+                        "autoplay": "",
+                        "controls": ""
+                    },
+                    on: {
+                        "start": _vm.onstart,
+                        "pause": _vm.onpause,
+                        "finish": _vm.onfinish,
+                        "fail": _vm.onfail
+                    }
+                }), _c('text', {
+                    staticClass: ["info"]
+                }, [_vm._v("state: " + _vm._s(_vm.state))])], 1)
+            },
+            staticRenderFns: []
+        }
+        module.exports.render._withStripped = true
+
+        /***/
+    })
+    /******/
+]);
\ No newline at end of file
diff --git a/src/main/java/com/alibaba/weex/WXApplication.java b/src/main/java/com/alibaba/weex/WXApplication.java
index 7917529..c155743 100644
--- a/src/main/java/com/alibaba/weex/WXApplication.java
+++ b/src/main/java/com/alibaba/weex/WXApplication.java
@@ -21,6 +21,7 @@
 import android.app.Activity;
 import android.app.Application;
 import android.os.Bundle;
+import android.util.Log;
 import android.support.multidex.MultiDex;
 import android.text.TextUtils;
 import com.alibaba.android.bindingx.plugin.weex.BindingX;
@@ -52,6 +53,8 @@
 import com.taobao.weex.common.WXException;
 import com.taobao.weex.performance.WXAnalyzerDataTransfer;
 
+import java.lang.reflect.Method;
+
 public class WXApplication extends Application {
 
   @Override
@@ -118,6 +121,8 @@
       //Typeface nativeFont = Typeface.createFromAsset(getAssets(), "font/native_font.ttf");
       //WXEnvironment.setGlobalFontFamily("bolezhusun", nativeFont);
 
+      startHeron();
+
     } catch (WXException e) {
       e.printStackTrace();
     }
@@ -187,4 +192,16 @@
     }
   }
 
+  private void startHeron(){
+    try{
+        Class<?> heronInitClass = getClassLoader().loadClass("com/taobao/weex/heron/picasso/RenderPicassoInit");
+        Method method = heronInitClass.getMethod("initApplication", Application.class);
+        method.setAccessible(true);
+        method.invoke(null,this);
+        Log.e("Weex", "Weex Heron Render Init Success");
+     }catch (Exception e){
+        Log.e("Weex", "Weex Heron Render Mode Not Found", e);
+    }
+  }
+
 }
diff --git a/src/main/java/com/alibaba/weex/WXPageActivity.java b/src/main/java/com/alibaba/weex/WXPageActivity.java
index 2deec2e..68fd922 100644
--- a/src/main/java/com/alibaba/weex/WXPageActivity.java
+++ b/src/main/java/com/alibaba/weex/WXPageActivity.java
@@ -56,7 +56,9 @@
 import com.taobao.weex.WXSDKEngine;
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.appfram.navigator.IActivityNavBarSetter;
+import com.taobao.weex.common.RenderTypes;
 import com.taobao.weex.common.WXRenderStrategy;
+import com.taobao.weex.render.WXAbstractRenderContainer;
 import com.taobao.weex.ui.component.NestedContainer;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXVContainer;
@@ -64,6 +66,7 @@
 import com.taobao.weex.utils.WXLogUtils;
 import java.io.File;
 import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
@@ -223,25 +226,32 @@
   }
 
   private void loadWXfromService(final String url) {
-
-    Log.d("test->", "on ActivityCreate ,loadWXfromService: ");
-
     mProgressBar.setVisibility(View.VISIBLE);
 
     if (mInstance != null) {
-      mInstance.destroy();
+       mInstance.destroy();
+       mContainer.removeAllViews();
     }
 
-    RenderContainer renderContainer = new RenderContainer(this);
-    //mInstance = new WXSDKInstance(this);
-    mInstance = WXPreLoadManager.getInstance().offerPreInitInstance(url);
-    if (null != mInstance){
-      mInstance.init(this);
-    }else {
+    WXAbstractRenderContainer renderContainer = null;
+    if(url.contains(RenderTypes.RENDER_TYPE_HERON_URL_PARAM)){
       mInstance = new WXSDKInstance(this);
+      mInstance.setRenderType(RenderTypes.RENDER_TYPE_HERON);
+      renderContainer = getHeronContainer(mInstance);
+      if(renderContainer == null){
+          mInstance.destroy();
+      }
     }
-
-    mInstance.setRenderContainer(renderContainer);
+    if(renderContainer == null){
+      renderContainer = new RenderContainer(this);
+      mInstance = WXPreLoadManager.getInstance().offerPreInitInstance(url);
+      if (null != mInstance){
+        mInstance.init(this);
+      }else {
+        mInstance = new WXSDKInstance(this);
+      }
+    }
+    mInstance.setWXAbstractRenderContainer(renderContainer);
     mInstance.registerRenderListener(this);
     mInstance.setNestedInstanceInterceptor(this);
     mInstance.setBundleUrl(url);
@@ -268,6 +278,8 @@
           }
           else if (TextUtils.equals(uri.getQueryParameter("__data_render"), Boolean.TRUE.toString())){
             mInstance.render(TAG, new String(task.response.data, "UTF-8"), mConfigMap, null, WXRenderStrategy.DATA_RENDER);
+          }else if (TextUtils.equals(uri.getQueryParameter("__json_render"), Boolean.TRUE.toString())){
+            mInstance.render(TAG, new String(task.response.data, "UTF-8"), mConfigMap, null, WXRenderStrategy.JSON_RENDER);
           } else {
             mInstance.render(TAG, new String(task.response.data, "utf-8"), mConfigMap, null, WXRenderStrategy.APPEND_ASYNC);
           }
@@ -287,6 +299,21 @@
     WXHttpManager.getInstance().sendRequest(httpTask);
   }
 
+
+  private WXAbstractRenderContainer getHeronContainer(WXSDKInstance instance){
+    try{
+      Class containerClass =  getClassLoader().loadClass("com.taobao.weex.heron.container.WXHeronRenderContainer");
+      Constructor constructor = containerClass.getConstructor(Context.class);
+      WXAbstractRenderContainer container = (WXAbstractRenderContainer) constructor.newInstance(this);
+      container.createInstanceRenderView(instance.getInstanceId());
+      return container;
+    }catch (Exception e){
+      Log.e("Weex", "getHeronContainer Error Use Native Container", e);
+      return null;
+    }
+  }
+
+
   /**
    * hot refresh
    */