OpenHarmony3.1-Ace-Formcomponent源碼解析
簡介
formcomponent用于展示桌面圖標和卡片。
卡片類似于安卓上的小部件,可以顯示于桌面上或者在一些其他系統服務頁面。
在展示卡片時,使用card_frontend解析hml標記語言,這是與應用展示不同的一種方式。OpenHarmony支持的應用界面開發有js的類web(hml+css+js)和ets兩種聲明式,在展示卡片時單獨使用了這種更輕量的卡片式(也是類web的,hml+css+json)。
圖標和卡片雖然來源和管理者不同,但在使用者這里,并無太大區別。桌面上的app圖標相當于1*1的卡片, 實現點擊跳轉到應用, 沒有動態刷新(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用的,目前并不是一種開發應用界面的方式。它的作用是解析卡片UI。
bridge/declarative_frontend/jsview下的js_form是將ets中的組件關聯到c++的ace引擎組件實例。
core/components/form下是ace引擎組件form_component。
系統架構
圖 1 系統架構
卡片提供者是ace_form_ability。卡片內容是hml+css+json,ace_form_ability負責里面數據的更新。
使用者是ace_ability,顯示卡片先創建ace中組件form_component, 其中的sub_container通過card_frontend來解析前端hml+css+json展示。
一個類比:formmgr相當于服務器,提供者相當于服務器上的服務,使用者相當于客戶端。
form_component能與卡片管理者formmgr通信,將卡片被安裝的事件告知formmgr。formmgr通知卡片提供者啟動ability。
圖 2 類圖
關鍵類介紹
- FormComponentAttribute、JSForm。
sdk的ts接口以及關聯的c類。它們是將應用里的控件翻譯為c對象。
前端FormComponent創建時設置的屬性包括:
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()中創建FormComponent時,將屬性通過RequestFormInfo傳給FormComponent實例。
設置的回調包括:
onAcquired、onError、onRouter、onUninstall。
- FormComponent、FormElement、RenderForm[RosenRenderForm、FlutterRenderForm]。
ace控件三件套,注意RenderForm是繼承于RenderSubContainer。
FormComponent保存卡片屬性。
FormElement在Prepare()中設置FormManagerDelegate的回調方法,在update()中創建SubContainer。
RenderForm中內容很少,因為真正繪制卡片是在SubContainer里面。 - FormManagerDelegate。
能夠與pipeline和FormMgr通信。在標準系統中,通過FormMgr管理卡片;[在lite系統中,沒有FormMgr,通過pipeline中的PlatformResRegister管理]。
FormMgr主動發起的ipc通過FormCallbackClient調用過來。 - FormManager。
本地管理SubContainer的單實例。 - SubContainer。
真正渲染卡片的地方。
outSidePipelineContext_是整個FormComponent的pipeline,pipelineContext_則是SubContainer自己渲染卡片時用的pipeline。這兩句代碼可以表明二者的關系:
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 初始化時序圖
- 首先前端創建FormComponent組件,并設置屬性和回調。
- 然后ace框架在vsync事件里創建FormElement和RenderForm。
- FormElement初始化創建FormManagerDelegate,并注冊事件回調。
- FormElement在update事件中創建SubContainer,然后通過FormManagerDelegate通知卡片管理者。
- RouterEvent只在lite系統使用,本文檔后面不做分析了。
管理中心發起事件流程
圖 4 加載成功時序圖
圖 5 數據更新時序圖
- 卡片數據更新由管理者回調通知,如果是首次則是Acquire流程,否則是Update流程。
- Acquire流程先將事件逐級回調通到應用js中,然后SubContainer調用CardFrontend展示卡片。
- Update流程只需要SubContainer調用CardFrontend更新卡片。
圖 6 卸載時序圖
卸載事件是通知應用的,應用在回調里可以將FormComponent去掉。
圖 7 提供者ability退出時序圖
圖 7 提供者ability退出時序圖
這個事件我的理解是提供者ability掛掉了,但是使用這這里繼續使用,通知管理者重新啟動起來。
交互事件流程
圖 8 交互事件時序圖
- 卡片加載時,SubContainer在runcard方法中,向pipeline注冊回調。
- pipeline響應到事件,回調SubContainer的方法。SubContainer回調FormElement,FormElement通過FormManagerDelegate發送給卡片管理者。
- 事件只支持router和message兩種類型。
- router事件多一步調用pipeline的OnActionEvent。
- 最終提供者ability響應事件。提供者是一個FormExtension的子類ability,在方法onEvent(formId, message)中處理事件。
- 與其他控件的最大區別就是,UI及UI事件代碼和事件響應代碼在兩個位置,并運行于兩個ability中。
總結
本文主要介紹了FormComponent控件的關鍵實現機制、主要類關系及重要的處理流程,側重于改控件本身,如果需要更完整的卡片原子服務流程,還需要分析卡片管理者FormMgr。兩者聯系起來學習,才能更清楚的理解完整的流程。