Android Weex 自定义 Component 指北

Weex 自定义 Component 开发这块,官方文档和网上示例都较少涉及。工做所需有所研究,总结此文以飨读者。前端

基础定义与注册

以下述代码所示,从 WXComponent 继承出来之后,复写四个构造器方法,就能够完成一个最简单可跑固然也显示不了任何东西的 WXComponet。java

须要说明的是 WXComponent 能够指定泛型 T,T extends View,用于指定WXComponent hostView 根布局的类型。这个仍是指定的比较好,在某些进阶用法中会须要这个类型。git

public class DemoWXComponent extends WXComponent<T> {
    public DemoWXComponent(WXSDKInstance instance, WXVContainer parent,
                           int type,
                           BasicComponentData basicComponentData) {
        super(instance, parent, type, basicComponentData);
    }

    public DemoWXComponent(WXSDKInstance instance, WXVContainer parent, String instanceId, boolean isLazy,
                           BasicComponentData basicComponentData) {
        super(instance, parent, instanceId, isLazy, basicComponentData);
    }

    public DemoWXComponent(WXSDKInstance instance, WXVContainer parent, boolean isLazy,
                           BasicComponentData basicComponentData) {
        super(instance, parent, isLazy, basicComponentData);
    }

    public DemoWXComponent(WXSDKInstance instance, WXVContainer parent,
                           BasicComponentData basicComponentData) {
        super(instance, parent, basicComponentData);
    }
}

使用这个 Component 以前,还须要把他注册进 WXSDKEngine。以下所示:
一次注册后,在Android程序销毁以前,能够一直使用这个 Component。无需 unregister,WXSDKEngine 也没有提供 unregister 方法,这是显而易见的,由于当前还未产生任何实例。github

WXSDKEngine.registerComponent("democomponent", DemoWXComponent.class);

值得一提的是 componet 名称,尽可能不要下划线中划线和大写字母,不然可能会踩坑。weex

好,接下来是 Weex JS 代码怎么调用。无需 import,直接使用,只要 register 方法已经被执行过了,以下所示:ide

<democomponent />

若是想要设定 props 怎么办,如 <democomponent source=test/>。布局

那就在 Componet 中增长以下:性能

@WXComponentProp(name = "source")
public void setSource(String source) {
    mSource = source;
    // or do some things
}

weex 会根据外部传入的 props,根据注解调用对应 props 的 set 方法。code

生命周期

显然,看了第一节,只能保证链路上 weex 自定义 Component 能跑起来,没有作其余任何事情。那么,为了能实现咱们须要的渲染和其余逻辑,就须要了解 Weex Componet 的生命周期。这里的生命周期,实质就是了解可 Override 的几个 WXComponent 方法,和他们的被调用的时机。这一块官方没有任何文档,全靠去 github 源码中看和试。component

必需 Override

initComponentHostView()

protected T initComponentHostView(@NonNull Context context) {
    // for example
    mComponentHostView = new FrameLayout(context);
    mComponentHostView.setId(R.id.fragment_content);
    return mComponentHostView;
}

用于生成根 View 返回给 Weex 来渲染。注意,不要在这里进行任何响应外界设入的 props 的渲染,由于此时极大可能 props 尚未被传入。

可选 Override

bindData()

@Override
public void bindData(WXComponent component) {
    super.bindData(component);
    // 这里进行 props 的响应渲染
}

super.bindData() 后便可响应 props 进行渲染,由于此时 props 的set方法都已经被调用过。

destroy()

@JSMethod
@Override
public void destroy() {
    super.destroy();
    // 进行自定义 Component 的必要销毁逻辑
}

若是有额外须要销毁的逻辑,须要写在 destroy 之中。weex 会在退出 WXActivity 或其余等同的时候调用。值得一提的是,我通常加一个 @JSMethod 注解,以提供前端 Weex 开发一个主动销毁的能力,避免须要的时候不能及时推代码生效,而要等到发版。

暴露方法

上段其实已经提到,怎样暴露一个 Component 方法给前端调用。以下所示:

@JSMethod
public void getDuration(JSCallback callback) {
    if (null != getCurrentShortVideoVh() && null != callback) {
        Map<String, Object> map = new HashMap<>(1);
        map.put("result", "value");
        callback.invoke(map);
    }
}

须要注意的是,直接把 void 改为返回值好比 boolean 而后试图 return 是没有用的,weex js 侧收不到。所以,必需要去使用回调来给返回值。如上所示。

DOM

Weex 新内核(WeexCore)将 Dom 层和 Layout 引擎下沉到 C++ 层实现,移除 Java 层的 DomObject,提高渲染性能和内核的可通用性。所以,github 最新版再也不能够获取到 WXComponent 中的 DomObject。

Tricks:强转

若是发现自定义 Component 的逻辑须要用到 Activity,而 WXComponent 只给你提供了 Context 的时候,不要慌,Weex 传入的 Context 其实能够强转 Activity。固然,以防万一,记得用 instance of 保护一下。

同理,若是你想要弹出一个 Fragment,结果发现本身须要一个 FragmentActivity 来getSupportFragmentManager(),不要慌,weex 传入的这个 Activity 也能够强转为FragmentActivity,一样记得加 instance of 保护,不然业务挂了不算个人,由于这毕竟是文档中的未定义行为。

相关文章
相关标签/搜索