在 WXSDKEngine 的 register()
方法中进行。这个方法里面是注册 Weex 原生自带的一些组件、模块以及 DomObject,如果你想扩展组件或者模块,也是需要走注册流程的,流程和这里的是一样的。
扩展 Android 的功能
注册 Component
1 | ├── WXSDKEngine.registerComponent() |
注册 Component
是在 WXSDKEngine.registerComponent()
方法中进行的,这个方法有几个重载方法,但最终都会执行到这个方法中来:
1 | public static boolean registerComponent(IFComponentHolder holder, boolean appendTree, String ... names) throws WXException { |
先来介绍一下 IFComponentHolder
这个参数。我们就以 WXText
的注册过来介绍一下。
1 | registerComponent( |
注册是实例化了一个 SimpleComponentHolder
类。这个类有几个方法,对应它的几个主要作用:
- createInstance():生成 Component 实现类的一个实例,比如
WXText
- getMethods(Class clz):获取实现类中
WXComponentProp
和JSMethod
注解标记的属性和方法。 - getMethods():获取所有
JSMethod
注解标记方法。 - getMethodInvoker(String name):获取某个方法对应的实现类的实体方法。
- getPropertyInvoker(String name):获取某个属性对应的实现类的实体方法。
1 | public SimpleComponentHolder(Class<? extends WXComponent> clz,ComponentCreator customCreator) { |
这里传入的两个参数分别是 Class
和 ComponentCreator
。
我们来看一下 WXText.Creator()
类。
1 | public static class Creator implements ComponentCreator { |
WXText.Creator()
类实现了 ComponentCreator
,在 createInstance()
方法中实例化了 WXText
类,这样就建立了和 Native Java 类的连接。
我们知道,IFComponentHolder
是继承自 ComponentCreator
的,那么这里在实例化 SimpleComponentHolder
又传入一个 ComponentCreator
实例是用来做什么的呢?
我们再来看一下 SimpleComponentHolder
实现的 createInstance()
方法:
1 | @Override |
这里其实就是调用的 WXText.Creator()
实例的 createInstance()
方法,并把 SimpleComponentHolder
绑定到生成的 WXComponent
上。这个方法什么时候使用我们后面再说。
再来看一下 WXComponentRegistry.registerComponent()
方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27public static boolean registerComponent(final String type, final IFComponentHolder holder, final Map<String, Object> componentInfo) throws WXException {
...
// 在js线程中执行注册操作
WXBridgeManager.getInstance()
.post(new Runnable() {
@Override
public void run() {
try {
Map<String, Object> registerInfo = componentInfo;
if (registerInfo == null){
registerInfo = new HashMap<>();
}
// 将 component 名字作为类型
registerInfo.put("type",type);
// 获取 `JSMethod` 注解标记的方法
// 这里或许有个疑问,自定义的属性去哪里了?
registerInfo.put("methods",holder.getMethods());
registerNativeComponent(type, holder);
registerJSComponent(registerInfo);
sComponentInfos.add(registerInfo);
} catch (WXException e) {
WXLogUtils.e("register component error:", e);
}
}
});
return true;
}
1 | private void invokeRegisterComponents(List<Map<String, Object>> components, List<Map<String, Object>> failReceiver) { |
这里再来介绍一下 appendTree
这个参数。
Weex 注册的 Component
有两种类型,一类是有 {@"append":@"tree"}
属性的标签,另一类是没有 {@"append":@"tree"}
属性的标签。
注册 DomObject
前面博客中也说过,DomObject 包括了 <template>
在 Dom 树中的所有信息,如 style、attr、event、ref(结点的唯一标识符)、parent、children 等。
在源码中注册过 Component 和 Moudle 后,紧接着是注册 DomObject。
1 | registerDomObject(WXBasicComponentType.TEXT, WXTextDomObject.class); |
注册流程:
1 | ├── WXSDKEngine.registerDomObject() |
WXDomRegistry.registerDomObject():
1 | public static boolean registerDomObject(String type, Class<? extends WXDomObject> clazz) throws WXException { |
可以看到,这部分是比较简单的。仅仅是把注册的 WXDomObject
放到一个 Map
中去,在生成 Native Dom 的时候再生成 WXDomObject
对象。
1 | ├── AbstractAddElementAction.addDomInternal() |