鸿蒙应用开发-ArkUI-X 全貌观

1,351 阅读9分钟

20241212更新

ArkUIX迁移了仓库,迁到了gitcode gitcode.com/ArkUI-X

介绍

gitee.com/arkui-x

ArkUI-X是一个声明式UI开发框架,可以让我们使用ArkTS写跨端UI,目前支持OpenHarmony、HarmonyOS、Android、iOS四个平台

设计总体说明

gitee.com/arkui-x/doc…

总体视图

image.png

设计思路如下:

  1. 采用 C++ 编写整体后端引擎代码,保持在多平台可移植性,最小化平台依赖,降低平台移植成本。
  2. 整体绘制采用自渲染机制,降低平台依赖,同时进一步提升绘制效果的一致性
  3. 抽象出平台适配层以及平台桥接层,以便不同平台的适配。

跨平台技术

  1. 研发模型,兼容OpenHarmony应用的Stage开发模型,支持基于ArkTS的声明式开发范式,可跨平台。
  2. 声明式UI后端引擎,包括布局,渲染,C++ UI组件,事件机制等,可跨平台。
  3. API扩展机制,基于NAPI机制,可跨平台。 不同平台需要各自扩展具体的API实现。
  4. 工具链/SDK, 工具链可跨平台,SDK需基于不同平台构建
  5. ArkUI依赖的ArkTS引擎以及图形引擎,也可跨平台

构建系统

ArkUI-X编译构建提供了一套基于GN和Ninja的编译构建框架

  1. 基础构建基于OpenHarmony的build仓
  2. 在OpenHarmony构建基础上新增Android和iOS编译工具链,以支持ArkUI跨平台SDK编译输出

SDK结构设计

ArkUI-X SDK目录结构介绍 gitee.com/arkui-x/doc…

image.png

启动入口

开发框架对应平台语言实现的Entrance,提供不同平台的基础入口环境

以Android为例

Stage模型下,Ability生命周期的入口为StageAbility,生命周期一直会通知到JsAbility,执行用户的生命周期回调方法,UI的页面是在onWindowStageCreated的生命周期中,调用Window的loadContent接口进行加载,创建ArkUI的实例并初始化渲染管线,将页面进行渲染显示

image.png

API扩展机制

JS API扩展机制,用于Native接口能力暴露到JS层,该机制直接复用OpenHarmony上的统一封装机制,扩展API (C++实现),并实现部分内置API

JS API需要遵循OpenHarmony的API定义,在不同平台上通过API扩展机制进行扩展。

image.png

环境配置

配置开发环境 gitee.com/arkui-x/doc…

下载DevEco Studio

 developer.huawei.com/consumer/cn…

image.png

配置OpenHarmonySDK

gitee.com/arkui-x/doc…

点击Edit指定下载目录,等待下载完成

image.png

配置Android SDK安装目录环境变量

gitee.com/arkui-x/doc…

配置环境变量ANDROID_HOME,设置Android SDK安装目录

export ANDROID_HOME=$HOME/Library/Android/sdk

配置 ArkUIX SDK

gitee.com/arkui-x/doc…

点击Edit指定下载目录,等待下载完成

image.png

配置ACE Tools(非必选)

 gitee.com/arkui-x/doc…

如果你需要使用命令行打包和编译,可以配置ACE Tool。主要是配置OHPM和ARKUIX_SDK_HOME环境变量

image.png

配置环境变量
export ARKUIX_SDK_HOME=/path-to-arkui-x-sdk
export PATH=${ARKUIX_SDK_HOME}/版本/arkui-x/toolchains/bin:$PATH

我这里是配置到了~/Documents/huawei/arkuix_sdk

# Android sdk
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/emulator
# 华为
export DecEcoIDE_SDK_Home=/Applications/DevEco-Studio.app/Contents
## 这里DEVECO_SDK_HOME名字不能改,ace需要使用到
export DEVECO_SDK_HOME=$DecEcoIDE_SDK_Home/sdk
# HDC_SERVER_PORT和HDC_SDK_PATH 是hdc需要配置的环境变量
export HDC_SERVER_PORT=7035
export HDC_SDK_PATH=$DEVECO_SDK_HOME/HarmonyOS-NEXT-DB1/openharmony/toolchains
export PATH=$HDC_SDK_PATH:$PATH
export PATH=$DecEcoIDE_SDK_Home/tools/hvigor/bin:$PATH
export PATH=$DecEcoIDE_SDK_Home/tools/ohpm/bin:$PATH

# 引入@arkui-x.bridge的时候需要用到
## 这里ARKUIX_SDK_HOME名字不能改,ace需要使用到
export ARKUIX_SDK_HOME=${HOME}/Documents/huawei/arkuix_sdk
export PATH=$ARKUIX_SDK_HOME/12/arkui-x/toolchains/bin:$PATH

# 仓颉
export CANGJIE_HOME=${HOME}/Documents/cangjie/cangjie
export PATH=${CANGJIE_HOME}/bin:${CANGJIE_HOME}/tools/bin:$PATH
hw_arch="aarch64"
export DYLD_LIBRARY_PATH=${CANGJIE_HOME}/runtime/lib/darwin_${hw_arch}_llvm:${DYLD_LIBRARY_PATH}

应用开发

应用开发指导  gitee.com/arkui-x/doc…

第一个例子

gitee.com/arkui-x/doc…

gitee.com/arkui-x/doc…

使用DevEco Studio创建一个空的ArkUI-X工程

image.png

进行编译输出

编译后的ArkTS代码、资源和平台胶水代码已生成到Android和iOS应用工程中

image.png

应用包结构

ArkUI-X应用目录结构设计思想

  1. 从OpenHarmony应用工程原生支持跨平台角度出发,在OpenHarmony应用工程之上叠加Android和iOS应用工程
  2. ArkTS代码和resources资源编辑仍在OpenHarmony侧完成
  3. Native代码在各自平台应用工程中完成

ArkUI-X应用工程结构说明 gitee.com/arkui-x/doc…

image.png

编译构建说明

ArkTS源码

ArkTS源码通过OpenHarmony SDK工具链生成abc(Ark Byte Code) ,并分别拷贝到Android和iOS应用工程作为平台应用资源进行管理。

ArkUI应用资源

ArkUI Resources资源也通过OpenHarmony SDK工具链进行编译,编译后的ArkUI资源分别拷贝到Android和iOS应用工程,作为平台应用资源进行管理。

ArkUI框架资源

ArkUI框架资源随ArkUI-X SDK进行发布,应用构建时会自动打包到ArkUI-X应用中,可保证ArkUI-X应用在各平台上UX渲染一致性

综上所述,Android平台上通过assets管理ArkTS编译产物、ArkUI应用资源和ArkUI框架资源,iOS平台上通过Bundle Resources管理ArkTS编译产物、ArkUI应用资源和ArkUI框架资源

image.png

注意点

Ability开发说明 https://gitee.com/arkui-x/docs/blob/master/zh-cn/application-dev/quick-start/start-with-ability-on-ios.md

StageViewController是Stage模型iOS端视图控制器基类,若要实现跨平台基础能力及触发对应ability生命周期,所有iOS端应用级别的视图控制器均要继承于StageViewController

StageApplication本质上是一个调度类,主要用于触发内部相关类实现路径解析与配置、注册应用相关的configuration信息、触发ability部分生命周期事件等

通过Stage模型开发iOS端应用指南 https://gitee.com/arkui-x/docs/blob/master/zh-cn/application-dev/quick-start/start-with-ability-on-ios.md

iOS端应用info配置里的bundleName需要与Ability的bundleName一致。

iOS端应用内的viewController的viewControllerName组成规则:Ability的moduleName + Ability的abilityName + “viewController”。

虽然这样说,但并不一定这样

从ArkUIX调用原生页面

ArkUI-X代码,调用startAbility后会走到原生代码的生命周期回调内

image.png

在iOS上会回调到下面的方法中。然后在方法中解析出bundleName、moduleName、abilityName。根据匹配调用对应的VC,调用哪个VC就是我们自己处理的了。

所以说上面 iOS端应用内的viewController的viewControllerName组成规则:Ability的moduleName + Ability的abilityName + “viewController”。这个规则可以不遵守,当然为了明确哪个VC遵守也没问题

  • (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options

image.png

从原生调用ArkUIX页面

原生端按照原生的push方式,打开一个ArkUIX页面。有几点要求

  1. 打开的VC是继承于StageViewController

  2. 传入的instanceName需要包含完整的  bundleName:moduleName:abilityName,这里是为了让ArkUIX找到要加载的资源

  3. 传入的params格式有要求

    1. 最外层是一个字典,字典内params是一个数组
    2. 数组中每一个元素是一个对象,每个对象包含key、value、type三个字段,分别表示传递的参数名称、参数值、参数类型
    3. 最后,对这个字典进行序列化成json字符串

image.png

image.png

ArkUI-X侧,通过Ability的onCreate或onNewWant接受传递过来的参数,然后我们就可以通过参数来确定加载哪个page,从而实现打开容器的某一页

image.png

桥接插件开发

开发者文档 https://gitee.com/arkui-x/docs/blob/master/zh-cn/application-dev/README.md

平台桥接(@arkui-x.bridge)  gitee.com/arkui-x/doc…

iOS 平台桥接开发指南  https://gitee.com/arkui-x/docs/blob/master/zh-cn/application-dev/tutorial/how-to-use-bridge-on-ios.md

iOS ArkUI-X插件开发指南 gitee.com/arkui-x/doc…

Android 平台桥接开发指南  gitee.com/arkui-x/doc…

Android ArkUI-X插件开发指南 gitee.com/arkui-x/doc…

插件的通信机制和RN很类似

  1. 在原生端,通过调用addPlugin添加插件,在插件里通过名称注册对应的BridgePlugin

image.png

image.png

#pragma mark - IMessageListener ArkUI侧发送的消息代理实现  
/**  
* Arkui测调用sendMessage 发送消息到IOS测,将会触发次方法的回调  
* @param data Arkui 传递过来的数据  
* return 返回值传递传递给Arkui测  
*/  
- (NSString*)onMessage:(id)data {  
NSLog(@"onMessage data: %@", data);  
return [NSString stringWithFormat:@"监听到:ArkTS给Native发送数据成功,发送的数据是 %@", data];  
}  
  
/**  
* iOS 通过sendMessage 方法发送消息到Arkui, Arkui成功接到消息后回调此方法传递结果  
* @param data Arkui 返回的信息  
*/  
- (void)onMessageResponse:(id)data {  
NSLog(@"onMessageResponse data: %@", data);  
  
// [self sendMessage:[NSString stringWithFormat:@"监听到:Native调用ArkTS方法%@ 成功,方法的返回值是 %@",  
// methodName,  
// resultValue ?: @"空"]];  
}  
  
#pragma mark - IMethodResult 用于监听平台侧调用ArkUI侧注册的方法的执行情况  
/**  
* ArkUI侧调用unRegisterMethod方法时将触发该接口,用于通知平台侧事件被注销了。  
* @param methodName ArkUI侧方法的名称  
* @param resultValue ResultValue 类 ,并将ArkUI侧方法的返回值传递给平台侧  
*/  
- (void)onSuccess:(nonnull NSString *)methodName resultValue:(nonnull id)resultValue {  
if (resultValue) {  
NSLog(@"bridge onSuccess data: %@", resultValue);  
}  
[self sendMessage:[NSString stringWithFormat:@"监听到:Native调用ArkTS方法%@ 成功,方法的返回值是 %@",  
methodName,  
resultValue ?: @"空"]];  
}  
  
/**  
* 平台侧调用ArkUI侧定义方法时,如果出错则触发该接口,并将出错信息返回平台侧。具体错误码查看ResultValue类中错误码或者接口文档  
* @param methodName ArkUI侧方法的名称  
* @param errorCode 错误码  
* @param errorMessage 错误信息  
*/  
- (void)onError:(nonnull NSString *)methodName errorCode:(ErrorCode)errorCode errorMessage:(nonnull NSString *)errorMessage {  
NSLog(@"Bridge: onError: %@ errorCode: %d errorMessage: %@",methodName, errorCode, errorMessage);  
  
[self sendMessage:[NSString stringWithFormat:@"监听到:Native调用ArkTS方法%@ 失败,失败信息是 %@",  
methodName,  
errorMessage ?: @"空"]];  
}  
  
/**  
* ArkUI侧调用unRegisterMethod方法时将触发该接口,用于通知平台侧事件被注销了。  
* @param methodName ArkUI侧方法的名称  
*/  
- (void)onMethodCancel:(nonnull NSString *)methodName {  
NSLog(@"Bridge: onMethodCancel");  
  
[self sendMessage:[NSString stringWithFormat:@"监听到:ArkTS调用unregisterMethod取消了注册的方法%@",  
methodName]];  
}

在ArkTS端通过 @arkui-x.bridge的API使用名称调用createBridge创建一个插件 image.png

image.png 5. 然后原生和ArkTS调用相应的API进行通信

支持动态化

动态化介绍 gitee.com/arkui-x/doc…

总体分成两类

  1. 框架动态化:指ArkUI跨平台开发框架本身可以做到动态下发,即应用发布时可以不带框架基础库,降低应用原始发布包体积,在需要时才从云端动态下发和执行加载;
  2. 特性动态化:指用ArkTS语言开发的特性可以做到动态化,和宿主应用解耦,独立发布、升级版本;

框架动态化是指依赖的动态库可以动态下载,只有Android支持,iOS不支持

特性动态化是指作为资源的abc文件和对应的文件资源,module等

不完全的API支持

支持的组件范式

除鸿蒙特有的组件外,基本所有组件都能支持。支持占比90%左右

ArkUIX 支持API developer.huawei.com/consumer/cn…

鸿蒙原生API gitee.com/arkui-x/doc…

支持的接口

ArkUIX支持的接口大概占鸿蒙的70%左右,其中的剩余部分主要是ArkUI以及鸿蒙的独有能力

资料

  1. ArkUI-X 仓库 gitee.com/arkui-x
  2. ArkUI-X SDK目录结构介绍 gitee.com/arkui-x/doc…
  3. 2.0.0-beta1发布说明 https://gitee.com/arkui-x/docs/blob/master/zh-cn/release-notes/ArkUI-X-v2.0.0-beta1.md
  4. ArkUI-X应用适配层 gitee.com/arkui-x/app…
  5. iOS平台的适配层 gitee.com/arkui-x/ark…
  6. iOS ArkUI-X 插件开发 gitee.com/arkui-x/doc…
  7. 联动编译 gitee.com/arkui-x/doc…
  8. Android平台的适配层 gitee.com/arkui-x/ark…
  9. Android ArkUI-X 插件开发 https://gitee.com/arkui-x/docs/blob/master/zh-cn/application-dev/tutorial/how-to-use-arkui-x-plugin-on-android.md
  10. 官方提供的一些插件 gitee.com/arkui-x/plu…
  11. ArkUI-X 应用开发 https://gitee.com/arkui-x/docs/blob/master/zh-cn/application-dev/README.md
  12. ArkUI-X 文档 gitee.com/arkui-x/doc…