Weex frame source analysis (the Android) (a)

A, weexSDK initialization process

WXSDKEngine.initialize(Application application,InitConfig config);

// WXSDKEngine init method has been abandoned, weex initialization initialize method requires the use of the following

public static void initialize (the Application file application, InitConfig config) {

  the synchronized (mlock) {

    // if already initialized less direct return

    IF (mIsInit) {

      return;

    }

    Long Start = System.currentTimeMillis ();

    WXEnvironment.sSDKInitStart = Start;

    IF (WXEnvironment.isApkDebugable ()) {

      WXEnvironment.sLogLevel = LogLevel.DEBUG;

    } the else {

IF (! WXEnvironment.sApplication = null) {

  WXEnvironment = LogLevel.WARN .sLogLevel;

} the else {

  WXLogUtils.e (the TAG, "WXEnvironment.sApplication IS" + WXEnvironment.sApplication);

}

    }

    doInitInternal (file application, config);

    = System.currentTimeMillis WXEnvironment.sSDKInitInvokeTime () - Start;

    WXLogUtils.renderPerformanceLog ( "SDKInitInvokeTime", WXEnvironment.sSDKInitInvokeTime);

    // weex monitoring performance of a detector initialization

    WXPerformance.init ();



    mIsInit = to true;

  }

}
This the final method calls doInitInternal (application, config), if the rest of the code portion disposed t apk and log the debug mode, the time required to initialize calculation weexSDK like. So then look at the code doInitInternal (application, config) of.

static void doInitInternal Private (Final application the Application, Final InitConfig config) {

  // Here WXEnvironment the application to assign, to facilitate subsequent use

   WXEnvironment.sApplication = application;

IF (application == null) {// is empty, the given application

  WXLogUtils. E (the TAG, "IS doInitInternal null file application");

  WXExceptionUtils.commitCriticalExceptionRT (null,

        WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT,

        "doInitInternal",

        WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT.getErrorMsg () + "WXEnvironment sApplication IS null",

        null);

}

   // environment initialization With weex, identification set to false

   WXEnvironment.JsFrameworkInit = to false;



   // Get the unique instance of a single embodiment WXBridgeManager mode, opening a secure WXBridgeManager weex thread initialization frame.

   // open the details of the security thread temporarily get to the bottom, here mainly to see the initialization process weex framework

   WXBridgeManager.getInstance (). POST (new new Runnable () {

     @Override

     public void RUN () {

        // initialization start time

       long start = System. with currentTimeMillis ();

       // Get WXSDKManager example

       WXSDKManager WXSDKManager.getInstance sm = ();

       // initialize using sm listening weex frame, we can WXSDKManager.registerStatisticsListener ()

       // register a listener

       sm.onSDKEngineInitialize ();

       // set CI weex frame

       IF (config = null!) {

         sm.setInitConfig (config);

       }

       // initialization file loader so, the latter two parameters are loaded at initialization and listeners.

       WXSoInstallMgrSdk.init (file application,

                             SM .getIWXSoLoaderAdapter (),

                             sm.getWXStatisticsListener ());

       // load the library so as not to set IWXSoLoaderAdapter custom, then the use of the system default load

       boolean isSoInitSuccess = WXSoInstallMgrSdk.initSo (V8_SO_NAME, 1 , config = null config.getUtAdapter (!?): null);

       IF (! isSoInitSuccess) {// load failure error

     WXExceptionUtils.commitCriticalExceptionRT (null,

           WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT,

           "doInitInternal",

           WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT.getErrorMsg () + "isSoInit to false",

           null);





         return;

       }

       // use WXSDKManager initialization jsFramwork, is to speak in assets under weexSdk js file copied to the cache directory, so use the native method execution

       sm.initScriptsFramework:; (config = null config.getFramework () null!?)

      

       // initialize the elapsed time is calculated

       WXEnvironment.sSDKInitExecuteTime = System.currentTimeMillis () - Start;

       WXLogUtils.renderPerformanceLog ( "SDKInitExecuteTime", WXEnvironment.sSDKInitExecuteTime);

     }

   });

   // number of built-in register weexSDK and Component Module1

   Register ();

}
Second, component (component) registration process

According to the official website of weex process, first of all we will call WXSDKEngine of registerComponent (String type, Class <? Extends WXComponent> clazz) method.

We find this approach WXSDKEngine source code:

static boolean registerComponent public (of the type String, Class <? the extends WXComponent> clazz) throws WXException {

  return WXComponentRegistry.registerComponent (of the type, new new SimpleComponentHolder (clazz), new new HashMap <String, Object> ());

}
We find that the method actually is called WXComponentRegistry.registerComponent (xx, xx, xx) method, we first SimpleComponentHolder note that follow-up will be used. So we tracked WXComponentRegistry view registerComponent method of implementation.

the synchronized static Boolean registerComponent public (Final String type, Final IFComponentHolder Holder, Final the Map <String, Object> ComponentInfo) throws WXException {

  IF (Holder == null || TextUtils.isEmpty (type)) {

    return to false;

  }

  // Execute Task js the thread to the make the Sure in the Register the order iS AS at the Same, the order method, the invoke the Register.

  // perform this task in the registration component js thread, to ensure consistency with the order of registration method call our registered components.

  WXBridgeManager.getInstance ()

      .post (the Runnable new new () {

    @Override

    public void RUN () {

      the try {

        the Map <String, Object> = registerInfo ComponentInfo;

        IF (registerInfo == null) {

          registerInfo new new = the HashMap <> ();

        }



        // set the registration information 

        registerInfo.put ( "of the type", of the type);

        // Holder before class so that we pay attention to SimpleComponentHolder

        registerInfo.put ( "Methods", holder.getMethods ());

        // generate native component mapping

        registerNativeComponent (type, holder);

        // pass the registration information to the component jsFramwork, js generated natively vue parsing component is required Json mapping

        registerJSComponent (registerInfo);

        // parse js sComponentInfos is required classes, registration information contains all components

        sComponentInfos.add ( registerInfo);

      } the catch (WXException E) {

        WXLogUtils.e ( "Register Component error:", E);

      }

    }

  });

  return to true;

}
there are more than a few lines of code in the tracking code for further analysis:

1、holder.getMethods();

holder of the object that is here before so that we pay attention to the new SimpleComponentHolder (clazz), we look at the source code to track implementation of this method

public static Pair<Map<String,Invoker>,Map<String,Invoker>> getMethods(Class clz){

  Map<String, Invoker> methods = new HashMap<>();

  Map<String, Invoker> mInvokers = new HashMap<>();


  Annotation[] annotations;

  Annotation anno;

  try {

    for (Method method : clz.getMethods()) {

      try {

        annotations = method.getDeclaredAnnotations();

        for (int i = 0, annotationsCount = annotations.length;

             i < annotationsCount; ++i) {

          anno = annotations[i];

          if(anno == null){

            continue;

          }

          if (anno instanceof WXComponentProp) {

            String name = ((WXComponentProp) anno).name();

            methods.put(name, new MethodInvoker(method,true));

            break;

          }else if(anno instanceof JSMethod){

            JSMethod methodAnno = (JSMethod)anno;

            String name = methodAnno.alias();

            if(JSMethod.NOT_SET.equals(name)){

              name = method.getName();

            }

            mInvokers.put(name, new MethodInvoker(method,methodAnno.uiThread()));

            break;

          }

        }

      } catch (ArrayIndexOutOfBoundsException | IncompatibleClassChangeError e) {

        //ignore: getDeclaredAnnotations may throw this

      }

    }

  } The catch (an IndexOutOfBoundsException E) {

    e.printStackTrace ();

    // the ignore: On May getMethods the this the throw

  }

  return new new Pair <> (Methods, mInvokers);

}
code is very simple, we can see that this method for obtaining the register Component all properties and methods, and to map them two collection methods, the last two packages to map Pair returned.

Time is resolved by the object of WXComponent.Class acquired all of its properties and methods (through WXComponentProp and JSMethod notes).

After successfully acquiring registerInfo.put ( "methods", holder.getMethods ()); these properties and methods information into the registration information assembly.

 

2、registerNativeComponent(type, holder);

This method is used to generate a map belonging to the native components for parsing of js files, we also look at the implementation of this method.

//WXComponentRegistry.java

Private static Boolean registerNativeComponent (String type, IFComponentHolder Holder) {WXException throws

  the try {

    holder.loadIfNonLazy ();

    sTypeComponentMap.put (type, Holder);

  } the catch (ArrayStoreException E) {

    e.printStackTrace ();

    / / the ignore: ArrayStoreException: Not java.lang.String CAN bE aN Array Stored in the java.util.HashMap type of HashMapEntry $ []

  }

  return to true;

}
 holder.loadIfNonLazy (); this line calls the method SimpleComponentHolder holder for the loadIfNonLazy the load is actually the component properties and methods of information stored in SimpleComponentHolder type of the object holder, the holder will be saved after the sTypeComponentMap, which is a collection of maps map a component assembly, it is a static variable. And with the realization of the subsequent sComponentInfos js file parsing component assembly (Json compiled into native object mapping resolved into components).

loadIfNonLazy () method implementation below, is relatively simple, not described in detail, see annotations to.

//SimpleComponentHolder.java

@Override

public void loadIfNonLazy () {

// Get all annotations class

  the Annotation [] Annotations mClz.getDeclaredAnnotations = ();

  for (the Annotation Annotation:

    Annotations) {

    IF (Annotation the instanceof the Component) {

      ! IF (( (the component) Annotation) .lazyload () && mMethodInvokers == null) {

        // component class methods and properties obtained by this process, and save

        Generate ();

      }

      return;

    }

  }

}

Private Generate the synchronized void () {

  IF ( WXEnvironment.isApkDebugable ()) {

    WXLogUtils.d (the TAG, "the Generate the Component:" + mClz.getSimpleName ());

  }

  // () method and a method of acquiring attribute information getMethods

  Pair <the Map <String, Invoker>, the Map <String, Invoker >> methodPair = getMethods (mClz);

  // save the information to their own properties and methods

  mPropertyInvokers = methodPair.first;

  mMethodInvokers = methodPair.second;

}

. 3, registerJSComponent (registerInfo );

This method and the method for converting the attribute information of the object into components Json object.

//WXComponentRegistry.java

Private static Boolean registerJSComponent (the Map <String, Object> ComponentInfo) {WXException throws

  the ArrayList <the Map <String, Object >> = new new COMS the ArrayList <> ();

  coms.add (ComponentInfo);

  WXSDKManager.getInstance ( ) .registerComponents (COMS);

  return to true;

}
//WXSDKManager.java

public void RegisterComponents (List <the Map <String, Object >> Components) {

  mBridgeManager.registerComponents (Components);

}
finally call it is invokeRegisterComponents method of WXBridgeManager. To achieve the following, we combine a comment to explain the implementation process.

//WXBridgeManager.java

/ **
* Registered Component
* /

public void RegisterComponents (Final List <the Map <String, Object >> Components) {

  space between the thread returns // js processor or collection of components to

  if (mJSHandler = components null == null || =

      || components.size () == 0) {

    return;

  }

 // for the component registration in JsThred

  POST (the Runnable new new () {

    @Override

    public void RUN () {

      invokeRegisterComponents (components, mRegisterComponentFailList);

    }

  }, null);

}

// Register assembly

Private void invokeRegisterComponents (List <the Map <String, Object >> components, List <the Map <String, Object >> failReceiver) {

 // failReceiver a component failure is registered collection

 IF (Components == failReceiver) {

    the throw new new a RuntimeException ( "Not use the Fail Should Receiver Source.");

  }

 // will not complete initialization jsFramwork assembly into collections registration failure

  IF {(isJSFrameworkInit ()!)

    WXLogUtils. E ( "[WXBridgeManager] invokeRegisterComponents: framework.js uninitialized.");





    for (the Map <String, Object> CoMP: Components) {

      failReceiver.add (CoMP);

    }

    return;

  }

  IF (Components == null) {

    return;

  }

 

  // assembly through the mapping information which was converted to Json

  WXJSObject [] args = {new new WXJSObject (WXJSObject.JSON,

      WXJsonUtils.fromObjectToJSONString (components))};

  the try {

   // execJS WXBridge by invoking native methods of (), call main.js in registerComponent method of registering components

    mWXBridge.execJS("", null, METHOD_REGISTER_COMPONENTS, args);

  } catch (Throwable e) {

    WXLogUtils.e("[WXBridgeManager] invokeRegisterComponents ", e);

WXExceptionUtils.commitCriticalExceptionRT(null,

     WXErrorCode.WX_KEY_EXCEPTION_INVOKE_REGISTER_CONTENT_FAILED,

     METHOD_REGISTER_COMPONENTS,

     WXErrorCode.WX_KEY_EXCEPTION_INVOKE_REGISTER_CONTENT_FAILED.getErrorMsg()

           + args.toString()

           + WXLogUtils.getStackTrace(e),

     null);

  }

}

三、模块(Module)注册流程

Here is the relevant implementation code, just write a brief comment, module and component registration registration process is very similar and is not described in detail, you can try your own interest to read the source code analysis.

//WXSDKEngine

public static boolean registerModule(String moduleName, Class<? extends WXModule> moduleClass) throws WXException {

  return registerModule(moduleName, moduleClass,false);

}

public static <T extends WXModule> boolean registerModule(String moduleName, Class<T> moduleClass,boolean global) throws WXException {

  return moduleClass != null && registerModule(moduleName, new TypeModuleFactory<>(moduleClass), global);

}

public static <T extends WXModule> boolean registerModule(String moduleName, ModuleFactory factory, boolean global) throws WXException {

  //在WXSDKEngine中最终调用WXModuleManager.registerModule(moduleName, factory,global)

  return WXModuleManager.registerModule(moduleName, factory,global);

}
WXModuleManager //

/ **
* Module to the Register JavaScript and Android
* /

public static boolean registerModule (Final String moduleName, moduleFactory Factory's Final, Final, Ltd. Free Join boolean) throws WXException {

  IF (moduleName == null || Factory's == null) {

    return to false;

  }

  IF (TextUtils.equals (moduleName, WXDomModule.WXDOM)) {

    WXLogUtils.e ( "Can not Registered Module1 with name 'DOM'.");

    return to false;

  }


  the try {

    // do not know why writing this code because behind the implementation of the same code, the object is to hold TypeModuleFactory Module class information stored in the sModuleFactoryMap // go. Do not know the source wrong, Takami students have requested wing

    sModuleFactoryMap.put (moduleName, new new ModuleFactoryImpl (Factory));

  } the catch (the Throwable E) {


  }


  //execute task in js thread to make sure register order is same as the order invoke register method.

  WXBridgeManager.getInstance()

          .post(new Runnable() {

            @Override

            public void run() {

              if (sModuleFactoryMap != null && sModuleFactoryMap.containsKey(moduleName)) {

                WXLogUtils.w("WXComponentRegistry Duplicate the Module name: " + moduleName);

              }

              try {

                //原生代码中注册module模块的类信息

                registerNativeModule(moduleName, factory);

              } catch (WXException e) {

                WXLogUtils.e("registerNativeModule" + e);

              }



              if (global) {

                try {

                  WXModule wxModule = factory.buildInstance();

                  wxModule.setModuleName(moduleName);

                  sGlobalModuleMap.put(moduleName, wxModule);

                } catch (Exception e) {

                  WXLogUtils.e(moduleName + " class must have a default constructor without params. ", e);

                }

              }

              registerJSModule(moduleName, factory);

            }

          });

  return true;

}
//原生代码中注册module模块的类信息

static boolean registerNativeModule(String moduleName, ModuleFactory factory) throws WXException {

  if (factory == null) {

    ; return to false

  }


  {the try

    IF {(sModuleFactoryMap.containsKey (moduleName)!)

      save // will hold information of the Module class object to the sModuleFactoryMap TypeModuleFactory go

      sModuleFactoryMap.put (moduleName, new new ModuleFactoryImpl (Factory));

    }

  } the catch ( E ArrayStoreException) {

    e.printStackTrace ();

    // the ignore:

    // On May the throw the this Exception:

    //java.lang.String Not CAN BE AN Array Stored in the java.util.HashMap type of HashMapEntry $ []



    WXLogUtils.e ( " [WXModuleManager] registerNativeModule moduleName Error: "+ + moduleName" Error: "+ e.toString ());

  }

  return to true;

}


method // registration module and the module name information in Js

static boolean registerJSModule(String moduleName, ModuleFactory factory) {

  Map<String, Object> modules = new HashMap<>();

  modules.put(moduleName, factory.getMethods());

  WXSDKManager.getInstance().registerModules(modules);

  return true;

}
//WXBridgeManager

private void invokeRegisterModules(Map<String, Object> modules, List<Map<String, Object>> failReceiver) {

  if (modules == null || !isJSFrameworkInit()) {

    if (!isJSFrameworkInit()) {

      WXLogUtils.d("[WXinvokeRegisterModulesBridgeManager] invokeRegisterModules: framework.js uninitialized.");

    }

    failReceiver.add(modules);

    return;

  }


  //将modules转换成WXJSObject   

  WXJSObject[] args = {new WXJSObject(WXJSObject.JSON,

      WXJsonUtils.fromObjectToJSONString(modules))};

  try {

   //调用WXBrige的native方法在js中注册module 

    mWXBridge.execJS("", null, METHOD_REGISTER_MODULES, args);

    try {

      Iterator<String> iter = modules.keySet().iterator();

      while (iter.hasNext()) {

        String module = iter.next();

        if (module != null) {

          WXModuleManager.resetModuleState(module, true);

          WXLogUtils.e("[WXBridgeManager]invokeRegisterModules METHOD_REGISTER_MODULES success module:" + module);

        }


      }

    } catch (Throwable e) {

    }

  } catch (Throwable e) {

WXExceptionUtils.commitCriticalExceptionRT(null,

     WXErrorCode.WX_KEY_EXCEPTION_INVOKE_REGISTER_MODULES,

     "invokeRegisterModules", WXErrorCode.WX_KEY_EXCEPTION_INVOKE_REGISTER_MODULES.getErrorMsg() +

     " \n " + e.getMessage() + modules.entrySet().toString(),

     null );



    WXLogUtils.e("[WXBridgeManager] invokeRegisterModules:", e);

  }

}
--------------------- 

Guess you like

Origin www.cnblogs.com/ly570/p/11007573.html