#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析 原创 精华

深开鸿
发布于 2022-6-23 18:04
浏览
2收藏

本文正在参加星光计划3.0–夏日挑战赛

作者:吴亮亮

简介

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 系统架构
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

卡片提供者是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 类图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

关键类介绍

  • 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 初始化时序图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

  1. 首先前端创建FormComponent组件,并设置属性和回调。
  2. 然后ace框架在vsync事件里创建FormElement和RenderForm。
  3. FormElement初始化创建FormManagerDelegate,并注册事件回调。
  4. FormElement在update事件中创建SubContainer,然后通过FormManagerDelegate通知卡片管理者。
  • RouterEvent只在lite系统使用,本文档后面不做分析了

管理中心发起事件流程

图 4 加载成功时序图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

图 5 数据更新时序图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

  1. 卡片数据更新由管理者回调通知,如果是首次则是Acquire流程,否则是Update流程。
  2. Acquire流程先将事件逐级回调通到应用js中,然后SubContainer调用CardFrontend展示卡片。
  3. Update流程只需要SubContainer调用CardFrontend更新卡片。

图 6 卸载时序图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

  1. 卸载事件是通知应用的,应用在回调里可以将FormComponent去掉。

图 7 提供者ability退出时序图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

  1. 这个事件我的理解是提供者ability挂掉了,但是使用这这里继续使用,通知管理者重新启动起来。

交互事件流程

图 8 交互事件时序图
#夏日挑战赛#OpenHarmony3.1-ace-formcomponent源码解析-鸿蒙开发者社区

  1. 卡片加载时,SubContainer在runcard方法中,向pipeline注册回调。
  2. pipeline响应到事件,回调SubContainer的方法。SubContainer回调FormElement,FormElement通过FormManagerDelegate发送给卡片管理者。
  3. 事件只支持router和message两种类型。
  4. router事件多一步调用pipeline的OnActionEvent。
  5. 最终提供者ability响应事件。提供者是一个FormExtension的子类ability,在方法onEvent(formId, message)中处理事件。
  • 与其他控件的最大区别就是,UI及UI事件代码和事件响应代码在两个位置,并运行于两个ability中。

总结

本文主要介绍了FormComponent控件的关键实现机制、主要类关系及重要的处理流程,侧重于改控件本身,如果需要更完整的卡片原子服务流程,还需要分析卡片管理者FormMgr。两者联系起来学习,才能更清楚的理解完整的流程。

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建OpenHarmony生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2023-1-12 11:03:23修改
2
收藏 2
回复
举报
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

大佬图片有点看不清,方便传份到附件中吗

1
回复
2022-6-23 18:10:46
胡泉河_2021
胡泉河_2021 回复了 红叶亦知秋
大佬图片有点看不清,方便传份到附件中吗

同求.................

回复
2022-6-24 09:45:47
回复
    相关推荐