OpenHarmony3.1-Ace-Formcomponent源碼解析
??想了解更多關(guān)于開源的內(nèi)容,請訪問:??
簡介
formcomponent用于展示桌面圖標(biāo)和卡片。
卡片類似于安卓上的小部件,可以顯示于桌面上或者在一些其他系統(tǒng)服務(wù)頁面。
在展示卡片時,使用card_frontend解析hml標(biāo)記語言,這是與應(yīng)用展示不同的一種方式。OpenHarmony支持的應(yīng)用界面開發(fā)有js的類web(hml+css+js)和ets兩種聲明式,在展示卡片時單獨使用了這種更輕量的卡片式(也是類web的,hml+css+json)。
圖標(biāo)和卡片雖然來源和管理者不同,但在使用者這里,并無太大區(qū)別。桌面上的app圖標(biāo)相當(dāng)于1*1的卡片, 實現(xiàn)點擊跳轉(zhuǎn)到應(yīng)用, 沒有動態(tài)刷新(allowUpate=false)。 以下分析都以卡片來進行說明。
代碼位置
/foundation/ace/ace_engine/frameworks/
├──bridge
│ ├──card_frontend
│ │ ├──js_card_parser.h
│ │ ├──js_card_parser.cpp
│ │ ├──card_frontend.h
│ │ ├──card_frontend.cpp
│ │ ├──card_frontend_delegate.h
│ │ └──card_frontend_delegate.cpp
│ └──declarative_frontend/jsview
│ ├──js_form.h
│ └──js_form.cpp
└──core
├──common
│ ├──form_manager.h
│ └──form_manager.cpp
└──components/form
├──resource
│ ├──form_request_data.h
│ ├──form_callback_client.h
│ ├──form_manager_resource.h
│ ├──form_manager_resource.cpp
│ ├──form_manager_delegate.h
│ └──form_manager_delegate.cpp
├──form_component.cpp
├──form_component.h
├──form_element.cpp
├──form_element.h
├──render_form_creator.cpp
├──render_form.cpp
├──render_form.h
├──rosen_render_form.cpp
├──rosen_render_form.h
├──flutter_render_form.cpp
├──flutter_render_form.h
├──form_window.cpp
├──form_window.h
├──sub_container.cpp
└──sub_container.h
bridge/card_frontend雖然和declarative_frontend、js_frontend位于同一級目錄,但它實際上是給sub_container用的,目前并不是一種開發(fā)應(yīng)用界面的方式。它的作用是解析卡片UI。
bridge/declarative_frontend/jsview下的js_form是將ets中的組件關(guān)聯(lián)到c++的ace引擎組件實例。
core/components/form下是ace引擎組件form_component。
系統(tǒng)架構(gòu)
圖 1 系統(tǒng)架構(gòu)
卡片提供者是ace_form_ability??ㄆ瑑?nèi)容是hml+css+json,ace_form_ability負責(zé)里面數(shù)據(jù)的更新。
使用者是ace_ability,顯示卡片先創(chuàng)建ace中組件form_component, 其中的sub_container通過card_frontend來解析前端hml+css+json展示。
一個類比:formmgr相當(dāng)于服務(wù)器,提供者相當(dāng)于服務(wù)器上的服務(wù),使用者相當(dāng)于客戶端。
form_component能與卡片管理者formmgr通信,將卡片被安裝的事件告知formmgr。formmgr通知卡片提供者啟動ability。
圖 2 類圖
關(guān)鍵類介紹
- FormComponentAttribute、JSForm。
sdk的ts接口以及關(guān)聯(lián)的c類。它們是將應(yīng)用里的控件翻譯為c對象。
前端FormComponent創(chuàng)建時設(shè)置的屬性包括:
id、name、bundle、ability、module、dimension(1*2, 2*2, 2*4, 4*4)、temporary。
interface FormComponentInterface {
(value: {
id: number;
name: string;
bundle: string;
ability: string;
module: string;
dimension?: FormDimension;
temporary?: boolean;
}): FormComponentAttribute;
}
JSForm在Create()中創(chuàng)建FormComponent時,將屬性通過RequestFormInfo傳給FormComponent實例。
設(shè)置的回調(diào)包括:
onAcquired、onError、onRouter、onUninstall。
- FormComponent、FormElement、RenderForm[RosenRenderForm、FlutterRenderForm]。
ace控件三件套,注意RenderForm是繼承于RenderSubContainer。
FormComponent保存卡片屬性。
FormElement在Prepare()中設(shè)置FormManagerDelegate的回調(diào)方法,在update()中創(chuàng)建SubContainer。
RenderForm中內(nèi)容很少,因為真正繪制卡片是在SubContainer里面。 - FormManagerDelegate。
能夠與pipeline和FormMgr通信。在標(biāo)準(zhǔn)系統(tǒng)中,通過FormMgr管理卡片;[在lite系統(tǒng)中,沒有FormMgr,通過pipeline中的PlatformResRegister管理]。
FormMgr主動發(fā)起的ipc通過FormCallbackClient調(diào)用過來。 - FormManager。
本地管理SubContainer的單實例。 - SubContainer。
真正渲染卡片的地方。
outSidePipelineContext_是整個FormComponent的pipeline,pipelineContext_則是SubContainer自己渲染卡片時用的pipeline。這兩句代碼可以表明二者的關(guān)系:
auto&& window = std::make_unique<FormWindow>(outSidePipelineContext_);
pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(std::move(window), taskExecutor_, assetManager_, nullptr, frontend_, instanceId_);
渲染卡片使用的是CardFrontend。
- CardFrontend、CardEventHandler、CardFrontendDelegate、JsCardParser
卡片渲染引擎。
流程分析
初始化流程
圖 3 初始化時序圖
- 首先前端創(chuàng)建FormComponent組件,并設(shè)置屬性和回調(diào)。
- 然后ace框架在vsync事件里創(chuàng)建FormElement和RenderForm。
- FormElement初始化創(chuàng)建FormManagerDelegate,并注冊事件回調(diào)。
- FormElement在update事件中創(chuàng)建SubContainer,然后通過FormManagerDelegate通知卡片管理者。
- RouterEvent只在lite系統(tǒng)使用,本文檔后面不做分析了。
管理中心發(fā)起事件流程
圖 4 加載成功時序圖
圖 5 數(shù)據(jù)更新時序圖
- 卡片數(shù)據(jù)更新由管理者回調(diào)通知,如果是首次則是Acquire流程,否則是Update流程。
- Acquire流程先將事件逐級回調(diào)通到應(yīng)用js中,然后SubContainer調(diào)用CardFrontend展示卡片。
- Update流程只需要SubContainer調(diào)用CardFrontend更新卡片。
圖 6 卸載時序圖
卸載事件是通知應(yīng)用的,應(yīng)用在回調(diào)里可以將FormComponent去掉。
圖 7 提供者ability退出時序圖
圖 7 提供者ability退出時序圖
這個事件我的理解是提供者ability掛掉了,但是使用這這里繼續(xù)使用,通知管理者重新啟動起來。
交互事件流程
圖 8 交互事件時序圖
- 卡片加載時,SubContainer在runcard方法中,向pipeline注冊回調(diào)。
- pipeline響應(yīng)到事件,回調(diào)SubContainer的方法。SubContainer回調(diào)FormElement,F(xiàn)ormElement通過FormManagerDelegate發(fā)送給卡片管理者。
- 事件只支持router和message兩種類型。
- router事件多一步調(diào)用pipeline的OnActionEvent。
- 最終提供者ability響應(yīng)事件。提供者是一個FormExtension的子類ability,在方法onEvent(formId, message)中處理事件。
- 與其他控件的最大區(qū)別就是,UI及UI事件代碼和事件響應(yīng)代碼在兩個位置,并運行于兩個ability中。
總結(jié)
本文主要介紹了FormComponent控件的關(guān)鍵實現(xiàn)機制、主要類關(guān)系及重要的處理流程,側(cè)重于改控件本身,如果需要更完整的卡片原子服務(wù)流程,還需要分析卡片管理者FormMgr。兩者聯(lián)系起來學(xué)習(xí),才能更清楚的理解完整的流程。