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 保護,不然業務掛了不算個人,由於這畢竟是文檔中的未定義行爲。

相關文章
相關標籤/搜索