ArkUI-X案例解析

目前,已经有按照方案完成整体改造的4个Sample作为完整案例。

应用描述 链接
鸿蒙世界 HMOSWorld
溪村小镇 OxHornCampus
音乐专辑 MusicHome
购物应用 MultiShopping

下面以实际改造过程中遇到的经典问题进行案例详解。

Products共性拆分Products共性拆分

在拆分原工程products模块为两个hap时,将可以复用的代码进行抽象,存于features层main,被hap依赖使用。

首先识别可以复用的代码逻辑部分,以溪村小镇为例,应用启动页会轮播三张图片,而图片源的数据结构作为可复用部分,将其存放于features层main中。

模块main 对外暴露 数据结构

typescript 复制代码
// OxHornCampus\features\main\Index.ets

// 对外暴露数据源
export { splashImages } from './src/main/ets/viewmodel/SplashModel';

arkuix和harmonyos使用时添加对模块main的依赖,即可访问数据。

json5 复制代码
// OxHornCampus\products\phone\arkuix\oh-package.json5
// harmonyos同理

{
  "name": "arkuix",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "",
  "author": "",
  "license": "",
  "dependencies": {
    "@ohos/utils": "file:../../../commons/utils",
    "@ohos/map": "file:../../../features/map",
    "@ohos/zones": "file:../../../features/zones",
    "@ohos/train": "file:../../../features/train",
    //添加模块依赖
    "@ohos/main": "file:../../../features/main", 
  }
}

Products差异性性拆分

以鸿蒙世界为例,HarmonyOS Next设备上应用持有5个tab页,其中 tabs"溪村挑战赛" 使用了harmonyos的独有能力进行UI设计。由于无法通过Bridge实现跨平台改造,因此需要在Android/iOS平台部署时删除该tab页相关元素,同时相关数据结构等根据平台独立设计,分别存放于harmonyos.hap 和 arkuix.hap。

arkuix侧不存在"CHALLENGE"数据项。harmonyos侧存在"CHALLENGE"数据项。

最终实现效果

harmonyos包展示效果,存在tab页"溪村挑战赛"

arkuix包展示效果,没有tab页"溪村挑战赛"

使用支持跨平台的UI控件、属性、方法进行跨平台开发

在音乐专辑中,当音乐播放时,播放控制栏的音乐图标会执行旋转动画,实际上HarmonyOS Next与Android/iOS使用了两套逻辑实现。

在HarmonyOS Next上。使用@ohos.graphics.displaySync (可变帧率)实现动画效果。

typescript 复制代码
// DisplaySyncLocal.ets

import { displaySync } from '@kit.ArkGraphics2D';
import { DisplaySyncInterface } from '../Interface/DisplaySyncInterface';

export class DisplaySyncLocal implements DisplaySyncInterface {
  private static instance: DisplaySyncLocal;
  private backDisplaySyncSlow: displaySync.DisplaySync | undefined = undefined;

  public static getInstance(): DisplaySyncInterface {
    if (!DisplaySyncLocal.instance) {
      DisplaySyncLocal.instance = new DisplaySyncLocal();
    }
    return DisplaySyncLocal.instance;
  }

  public createAnimate(range: ExpectedFrameRateRange, frame: () => void): void {
    this.backDisplaySyncSlow = undefined;
    this.backDisplaySyncSlow = displaySync.create();
    this.backDisplaySyncSlow.setExpectedFrameRateRange(range);
    this.backDisplaySyncSlow.on('frame', frame);
  }

  public deleteAnimate(frame: () => void): void {
    if (this.backDisplaySyncSlow != undefined) {
      this.backDisplaySyncSlow?.off('frame', frame);
      this.backDisplaySyncSlow = undefined;
    }
  }

  public startAnimate(): void {
    if (this.backDisplaySyncSlow != undefined) {
      this.backDisplaySyncSlow?.start();
    }
  }

  public stopAnimate(): void {
    if (this.backDisplaySyncSlow != undefined) {
      this.backDisplaySyncSlow?.stop();
    }
  }
}

由于当前ArkUI-X框架未适配这套方法,在arkui-x侧实际上使用了@ohos.animator (动画)实现动画效果。

typescript 复制代码
// DisplaySyncArkUIX.ets

import { Animator, AnimatorResult } from '@kit.ArkUI';
import { DisplaySyncInterface } from '../Interface/DisplaySyncInterface';

export class DisplaySyncArkUIX implements DisplaySyncInterface {
  private static instance: DisplaySyncArkUIX;
  private backAnimator: AnimatorResult | undefined = undefined;

  public static getInstance(): DisplaySyncInterface {
    if (!DisplaySyncArkUIX.instance) {
      DisplaySyncArkUIX.instance = new DisplaySyncArkUIX();
    }
    return DisplaySyncArkUIX.instance;
  }

  public createAnimate(range: ExpectedFrameRateRange, frame: () => void): void {
    this.backAnimator = undefined;
    this.backAnimator = Animator.create({
      duration: 5000,
      easing: "linear",
      delay: 0,
      fill: "forwards",
      direction: "normal",
      iterations: -1,
      begin: 0,
      end: 1
    })
    this.backAnimator.setExpectedFrameRateRange(range);
    this.backAnimator.onFrame = frame;
  }

  public deleteAnimate(frame: () => void): void {
    if (this.backAnimator != undefined) {
      this.backAnimator.cancel();
      this.backAnimator = undefined;
    }
  }

  public startAnimate(): void {
    if (this.backAnimator != undefined) {
      this.backAnimator.play();
    }
  }

  public stopAnimate(): void {
    if (this.backAnimator != undefined) {
      this.backAnimator.pause();
    }
  }
}

关于DevEco Studio编译时报错问题解决

问题现象:DevEco Studio编译hap时报错:" xxx can't support crossplatform application. "

问题解析:由于使用了跨平台工程模版,DevEco Studio在进行静态编译检查时会检查跨平台标签"@crossplatform"。而在工程中会使用一些当前不支持跨平台的HarmonyOS 接口导致静态编译检查失败。

解决方法:

1.找到 IDE 里配套 OH-SDK;如果是HarmonyOS Next开发,则是HarmonyOS 里带的oh-sdk。

简便方法:前提需保证工程使用SDK为正确的。使用DevEco Studio打卡任一工程,在工程中打开并查看任一d.ts文件,于文件名右键点击-->选择 打开范围-->选择 Explorer 点击,打开的文件窗口即为当前工程所使用的SDK路径,于文件窗口回到SDK根目录执行第2步。

2.找到文件:" api_check_util.js "。文件在SDK中的相对路径为:

plaintext 复制代码
sdk\HarmonyOS-NEXT-DB1\openharmony\ets\build-tools\ets-loader\lib\fast_build\system_api\api_check_utils.js

3.在文件" api_check_util.js "中搜索关键字:CROSSPLATFORM_TAG_CHECK_ERROER,将其后边的 DiagnosticCategory.Error 修改为 DiagnosticCategory.Warning。

4.回到DevEco Studio 如果当前工程已编译过,先执行clean操作;之后执行操作: 点击文件-->选择 清理缓存 点击--> 勾选选项 --> 点击清除并重新启动。

约束与建议

本方案是依据ArkUI-X框架来实现的,应首先符合ArkUI-X框架的规格要求.

在应用UI方面存在的差异,是无法借助Bridge能力来弥补的。在此建议使用ArkUI-X框架中已经适配完毕的组件,这些组件功能相对稳定且较为全面。

应用改造过程中可能涉及通过Bridge框架使用平台原生接口方法,使用时需满足相应的原生系统版本要求。

相关推荐
坚果派·白晓明2 小时前
HarmonyOS NEXT端侧工程调用云侧能力实现业务功能
华为·harmonyos·项目实战·端云一体化
HarmonyOS小助手2 小时前
京东正式开源Taro on HarmonyOS C-API 版本,为鸿蒙应用跨端开发提供高性能框架
harmonyos·鸿蒙·harmonyos next·harmonyos 5.0·鸿蒙5·鸿蒙生态
白晓明3 小时前
端侧调用云存储实现头像存储
harmonyos
白晓明3 小时前
HarmonyOS NEXT端云一体化云侧云函数介绍和开发
前端·harmonyos
白晓明4 小时前
HarmonyOS NEXT端侧工程调用云函数能力实现业务功能
前端·harmonyos
六一二5 小时前
Cursor鸿蒙实战
harmonyos
脑极体5 小时前
鸿蒙星闪,智能生活交响乐的指挥家
华为·生活·harmonyos
中雨20255 小时前
HarmonyOS Next快速入门:函数和自定义构建函数
harmonyos
枫叶丹48 小时前
【HarmonyOS Next之旅】DevEco Studio使用指南(三十六) -> 配置构建(三)
华为·harmonyos·deveco studio·harmonyos next