注册 Module
1 | ├── WXSDKEngine.registerModule() |
注册 Module 的流程和注册 Component 流程比较类似。registerModule()
也有多个重载方法,但最终调用的是 WXModuleManager.registerModule()
方法。
在介绍 WXModuleManager.registerModule()
方法之前,我们先看一下它的参数之一 ModuleFactory
。这个类和注册 Component 时的 ComponentHolder 类比较类似。
一般情况下,我们会调用 registerModule(String moduleName, Class<T> moduleClass,boolean global)
方法来注册 Module,比如:
1 | registerModule("modal", WXModalUIModule.class, false); |
WXSDKEngine.registerModule(String moduleName, Class
1 | public static <T extends WXModule> boolean registerModule(String moduleName, Class<T> moduleClass,boolean global) throws WXException { |
这时候会以 WXModalUIModule.class
为参数生成一个 TypeModuleFactory
实例。它有三个作用分别对应三个方法:
- buildInstance():生成一个 Module 对应 class 的实例
- getMethods():获取 class 所有的 JSMethod 注解的方法
- getMethodInvoker(String name):获取注册 Module 提供的API的执行体
- generateMethodMap():解析该模块中的所有方法,并为它生成一个方法的执行体
MethodInvoker
先来看一下 TypeModuleFactory.generateMethodMap()
方法:
1 | private void generateMethodMap() { |
WXModuleManager.registerModule() 方法:
1 | public static boolean registerModule(final String moduleName, final ModuleFactory factory, final boolean global) throws WXException { |
Native 层的注册过程很简单,在 sModuleFactoryMap
中保存了 Module 的 Name 及对应的 ModuleFactory
,提供给 callModuleMethod()
方法调用。
1 | static boolean registerNativeModule(String moduleName, ModuleFactory factory) throws WXException { |
JS 层的注册也比较简单,调用 WXBridge.execJS()
注册。
WXBridgeManager.invokeRegisterModules()
1 | private void invokeRegisterModules(Map<String, Object> modules, List<Map<String, Object>> failReceiver) { |
Module 方法调用流程
方法执行流程图
1 | ├── WXBridge.callNativeModule |
代码分析
1 | public Object invoke(final Object target,final Invoker invoker,JSONArray args) throws Exception { |
从这个方法我们可以看出,如果模块的自定义方法需要返回值,那么就只能设置 @JSMethod(uiThread = false)
。相当于同步方法。
解析参数:paramClazzs
是模块中定义的方法的参数类型数组,args
是JS传递过来的参数数组。
1 | private Object[] prepareArguments(Type[] paramClazzs, JSONArray args) throws Exception { |
callback执行流程
为了测试 callback 的执行流程,我们自定义了下面模块:
1 | public class MyModule extends WXModule { |
调用该模块:
1 | weex.requireModule('myModule').testCallback({ |
下面来看一下 callback1 的调用流程:
1 | ├── SimpleJSCallback.invoke() |
在 callbackJavascript()
方法中,先通过 addJSTask()
方法在JS线程把执行回调函数的任务放到 mNextTickTasks
中,等待下次执行 invokeCallJSBatch()
时执行该任务。
1 | void callbackJavascript(final String instanceId, final String callback, |
1 | private void addJSEventTask(final String method, final String instanceId, final List<Object> params, final Object... args) { |
1 | private void invokeCallJSBatch(Message message) { |
解析参数:
WXJsonUtils.wsonWXJSObject(tasks):
1 | public static final WXJSObject wsonWXJSObject(Object tasks){ |
最后调用 JSON.toJSONString(obj)
方法把对象解析为 json 数据。
解析成 WXJSObject
类型的参数:1
[{"args":["1",{"method":"success","paras":["paraSuccess1","paraSuccess2"]},false],"method":"callback"}]