成为自己:鸿蒙 Harmony 工具篇

成为自己:鸿蒙 Harmony 工具篇

开发工具下载:developer.harmonyos.com/cn/develop/...

前言

「华为手机」、「鸿蒙系统」自发布以来,一直伴随着讨论、争议,直到今年华为通过 Mate60 手机和神秘的 "4.999G" 芯片打破僵局,再一次站在了科技界直至全社会的聚光灯下。「打破封锁」?「轻舟已过万重山」?「遥遥领先」?面对所有的赞叹声和质疑声,华为交出了自己的一份答卷,现在我们剥离掉所有的光环,从实际出发,以开发者的角度看看鸿蒙系统到底是一个怎样的存在,也许可以从中窥见从「质疑鸿蒙」到「成为鸿蒙」的成长历程。

鸿蒙是一个非常庞大的主题,所以笔者将通过分章节的方式,从「工具」、「系统」、「编码」、「实战」四个篇章来全方位介绍鸿蒙系统,作为鸿蒙系统的开篇,该篇主要介绍一些基础的开发概念、术语,以及使用 Harmony 提供的开发者工具,在搭建环境过程中会遇到的一些问题,解决方案,同时还会比对和原生 Android 开发 IDE 之前的异同,帮助 Android 开发者更好地了解并适应新的开发环境。

开发工具

鸿蒙的主开发 IDE 为 DevEco-Studio(DevelopEcology Studio,生态开发 Studio),和 Android Studio 一样,基于 IntelliJ 平台做的自定义 IDE。因此,对于 Java 开发者而言,DevEco 只是"在熟悉中带有一点点陌生"。

安装 Node.js

在安装好 DevEco 之后,首次点开需要开发者设置 Node.js 环境,并且有版本要求:

Node.js version: even-numbered version marked LTS, in the v14.19.1 to v16 range npm version: 6.14.16 or later

下载时需要注意选择 Node 长期维护的版本并且使用较新的版本安装包(可以选择使用自装包也可以通过 IDE 下载。有坑,见问题一)。

ohpm

ohpm(OpenHarmony Package Manager,亦称 ohsdkmgr),是鸿蒙系统的包管理工具(类似于 Android SDK Package Manager),支持查看、安装和卸载 SDK 组件,SDK 组件包括 API 和工具链,也需要独立安装。这里推荐直接在 DevEco IDE 中安装,能省事不少。

HarmonyOS SDK

和 Android SDK 相同,除了 Manager 工具之外,还需要下载鸿蒙系统用于开发的各个系统版本的 SDK APIs 和工具,也推荐直接在 DevEco IDE 中傻瓜式安装。从 SDK 大小看,275.93MB 中规中矩,大概是刚起步的原因,内容并不多。SDK 中包含了如下内容(Mac 中的下载路径:/Users/xxxx/Library/Huawei/Sdk):

3.1.0(API 9)
Previewer 3.2.3.6 75.00 MB
Toolchains 3.2.3.6 21.99 MB
OpenHarmony(API 9)
ArkTS 3.2.12.5 46.87 MB
JS 3.2.12.5 21.92 MB
Previewer 3.2.12.5 97.52 MB
Toolchains 3.2.12.5 12.64 MB

截止当前,SDK 提供的最高版本是 3.1.0 API 9(鸿蒙 4.0+ 的系统需要额外的企业账号授权才能体验),里面包含了两部分:Harmony SDKOpenHarmony SDK

HarmonyOS SDK VS OpenHarmony SDK 大家看到这里应该会有一个疑惑,HarmonyOS 和 OpenHarmony 是两个概念,有什么区别? 首先 OpenHarmony 是一个开源项目,有开放原子开源基金会(OpenAtom Foundation)孵化和运营。相当于 Android 的 AOSP,但不支持 Java 开发应用,不支持模拟器运行。 而 HarmonyOS 是在开源基础上,实现现有 Android 生态应用在部分搭载该 HarmonyOS 设备上运行(可以理解为鸿蒙过渡阶段,中间态)。既然如此,那么在开发语言支持方面,自然是支持 Java/C/C++ 的。 同时,值得开发者注意的是,OpenHarmony 和 HarmonyOS 的 API 略有差别,且打包签名的方式也不同,代码层面上的不同在后面「编码篇」我们在详细展开。

这里对不熟悉 ArkTS 的同学在简单解释下概念,ArkTS 是一个 TS 应用开发框架,支持 Node.js 和 WebAssembly(能力可扩展到 C/C++ 领域),所以它支持多种编程语言实现,ArkTS 涉及了多组件,如编译器 TS 前端、TS 后端、TS 运行时、TS 调试器等。其中,ArkTS Runtime 是 OpenHarmony 上 TS 应用使用的运行时,包含了 TS 对象的分配器以及垃圾回收器、符合 ECMAScript 规范的标准库、用于运行 Ark 前端组件生成的「方舟」字节码(ArkBytecode)的解释器、用于存储隐藏类的内联缓存、对外的函数接口(AFFI)等模块。

ArkTS 就可以理解为是 TypeScript 语言基础上的一个框架,该框架匹配了 ArkUI 框架,扩展了声明式 UI、状态管理等相应的能力,让开发者可以以更简洁、更自然的方式开发跨端应用。

ArkTS、TypeScrip t和 JavaScript 之间的关系: JavaScript 是一种属于网络的高级脚本语言,已经被广泛用于 Web 应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。 TypeScript 是 JavaScript 的一个超集,它扩展了 JavaScript 的语法,通过在 JavaScript 的基础上添加静态类型定义构建而成,是一个开源的编程语言。 ArkTS 兼容 TypeScript 语言,拓展了声明式 UI、状态管理、并发任务等能力。

HelloWorld

按照国际惯例,接触一门新的开发技术,首先从 Hello World 开始,那么在学习鸿蒙时,我们也从创建一个基础的工程开始。

首先,当选择「Create Project」时,DevEco 弹出的创建工程的选项只有两个:「Application」和「Atomic Service」,Application 很好理解,就是基于嵌入式或者移动端的「需要安装」的应用,而 Atomic Service 则是通过服务组件、二维码扫描、OneHop(基于 NFC 的不同应用或设备间数据无缝传输和交互的能力)方式通过的「免安装」服务。Atomic Service 等后续章节再来探索。我们先集中精力关注移动端「Application」的开发。

和 Android Studio 类似,只要我们在 DevEco 上选择 Application 的创建标签,它提供的是以「页面」维度的入口文件,区别在于 Android Studio 提供的是以 「Activity」 命名的入口文件(或者「活动」),而鸿蒙系统则称之为 「Ability」 ,从这可以看出一些有意思的点是,Android 的 Activity 聚焦的是「行为」,而鸿蒙的 Ability 注重的是「能力」,「行为」注重和用户的交互,而「能力」倾向的是边界的扩展,这和鸿蒙的「万物互联」思想是相辅相成的。(格局大了有没有)

VS

在创建工程上,还可以看出一点,就是鸿蒙在开发的时候,正在淡化边界,既然要做到「万物互联」,那么就不用去管当前的开发设备到底是在手机端、还是手表、亦或是电视还是自动驾驶等,IDE 提供的是能力的创建,而这个能力可以应用到各个设备端,当然是否真的能做到,我们接着往下看。

还有一点小区别,可以看下创建工程的左上角,DevEco 提供了所谓的「Template Market」,即模版市场,初心应该是提供开发这一些便捷的模版,减少开发成本,同时也能固定鸿蒙各个应用间的体验统一性,点进去看发现,目前只有一个「Shopping Mall」的 Template,后续可能还要依赖官方和开发者之间的支持,这里暂时按下不表。主页卡片上,DevEco 提供的和 Android Studio 类似的使用于不同应用类型的不同样式页面。作为一个有经验的开发者,我们就跳过「Empty Aliblity」这种简单的模版,直接上难度,走一个较为复杂的 「Category Ability」。

选中以后,进入下一步,一股熟悉感铺面而来:

定义工程名,语言只能选 ArkTS,Stage 和 FA 分别代表鸿蒙 API 4-8 和 API 9,还有目标设备,直接下一步 「Finish」。

这里可能会有人好奇,在 DevEco IDE 上连接 Android 设备,是否也可以进行工程的编译和运行,答案是否定的,如果是非鸿蒙系统,IDE 上并不会识别有设备连接到 IDE,理所当然也不能进行 Android 设备的编译调试。

工程结构

不出意外地出了意外,开始执行工程创建之后报错了,详见后面「问题」章节问题一

解决之后,继续探索。

包结构

我们先从 APP 包结构入手,具体看下打包后的产物长什么样子。当前鸿蒙支持 Stage 和 FA(Feature Ability)两种应用模型,我们来看下两者包体上的异同。

VS

从包结构里可以看出,对于 FA 模型,内部的 HAP 模块相对独立,每个 HAP 都包含了相同的 assets 和 config.json 类型代码、资源和数据,侧面印证了 FA 模型每个应用组件独享一个 ArkTS 引擎实例的现象。

Stage 模型与 FA 模型最大的区别在于:Stage模型中,多个应用组件共享同一个 ArkTS 引擎实例;而 FA 模型中,每个应用组件独享一个 ArkTS 引擎实例。因此在 Stage 模型中,应用组件之间可以方便的共享对象和状态,同时减少复杂应用运行对内存的占用。Stage 模型作为主推的应用模型,开发者通过它能够更加便利地开发出分布式场景下的复杂应用。

对于 IDE,相信接触过 Android Studio 的开发者都不陌生,对于一些开发调试工具、界面排布、入口等不再赘述,我们主要集中在工程结构上。

来看一下,工程几个重要的组成部分。这里不得不吐槽一句,作为官方的工程示例,同一个工程里,编码风格上既然包含了驼峰、小写、下划线、中线等多种命名风格,显得有那么点不统一和谐。

AppScope

存放整个应用公共的信息和资源,属于公共资源,对于各个 module 均可读。app.json5文件里存放了关于应用的配置信息,比如包名、版本号、应用名称、图标等,和 Android Manifest 类似。

这里对 json5 格式也做下进一步解释,json5 是 json 的超集,通过包含一些 ECMAScript5.1 的产物来减少 json 的限制,扩展 JSON 的语法。简单来说,json5 比 json 更加灵活,比如:

  1. json 只能使用""来表示 String 类型数据,而 json5 可以使用单引号
  2. json5 支持对数据进行注释,使可读性更高

举个例子:

arduino 复制代码
{
  "name": 'John',
  "age": 30,
  // this is a comment
  /* this is another comment */
  "email": "johndoe@example.com",
  "hobbies": [
    "reading",
    "coding",
    "music",
  ],
}

entry

默认的初始化入口模块,是应用的主模块,存放 HarmonyOS 应用的代码和资源,其中里面包含源码的目录为 /entry/src/main/ets,包含模块公共资源的目录为 /entry/src/main/resources。ets 下可根据实际开发定义不同的文件夹目录,如示例代码中使用了 MVVM 的工程架构。一般而言,pages 文件下存放的是页面相关的代码。

hvigor

类似于 Android 的 gradle 目录,存放了系统开发构建环境依赖的版本号

oh_modules

是工程的依赖包,存放工程依赖的源文件。

build-profile.json5

json 复制代码
{
  "app": {
    "signingConfigs": [],
    "compileSdkVersion": 9,
    "compatibleSdkVersion": 9,
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
      }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",
          "applyToProducts": [
            "default"
          ]
        }
      ]
    }
  ]
}

应用层级的配置文件,包括签名、产品配置、模块信息等,对标 Android 的 app 级别的 build.gradle + settings.gradle。

hvigorfile.ts

工程级编译构建任务脚本,hvigor 是基于任务管理机制实现的一款全新的自动化构建工具,主要提供任务注册编排,工程模型管理、配置管理等核心能力。听着比较抽象,可以先简单理解为构建脚本,我们在实际使用的时候再详细介绍。

oh-package.json5

工程级依赖配置文件,用于记录引入包的配置信息。

编译运行打包

在接下来,我们来看一下鸿蒙上应用的编译运行打包部分的情况。

当使用真机来进行编译运行时,会出现「没有签名」运行失败的情况,详见后面「问题」章节问题二。

解决了签名问题,终于可以在真机上运行了。然而,又出意外了,在正常进入 Demo 页面的之后,整个页面和交互就卡死了(没错,类似于 ANR 了),在屏幕上进行无意义的点击之后,彻底黑屏。更意外的是,当我点击 Log 里的截屏能力时,能正常截到图像,但真机却是黑屏。同时还影响了系统的稳定性,从后台切回来后,能正常显示页面,但是后台任务这里,又出现了异常显示。详见后面「问题」章节问题三。

打包

我们在"假设"应用没问题的情况下,自然而然地进入打产物包的阶段。在「Build」工具栏,我们看到产物有两种类型:Hap 和 APP,APP 无需赘述,我们了解下 Hap 是什么东西,HamonyOS Ability Package for short,我们从签名了解到,鸿蒙是以 Ability 为主要维度来构建应用的,而 Hap 是 Ability 的部署包(类似于 Module 的概念),同时 Ability 又分为了 FA(Feature Ability,HarmonyOS 早期版本,不再主推) 和 PA(Particle Ability) 两种类型,是组成应用的基本单元。FA 和 PA 的区别在于「有无 UI 元素」。

当我们选择构建 APP 类型时,生成的产物在 ProjectRootDir/build/outputs/default 下面,并且后缀是 .app。而选择 Hap 类型构建时,生成的产物后缀自然是 .hap,值得注意的是,无论 App 还是 Hap 都可以独立安装在鸿蒙设备上,App 可以上线应用市场。这么设计的初衷,可能还是基于各个 IoT 设备都能运行的考虑。

命令行工具

在鸿蒙的构建生态中,存在几种工具指令辅助进行开发,这里也做一个归纳总结:

命令 用途 常用指令 路径
sdkmgr HarmonyOS SDK命令行管理工具,支持查看、安装和卸载SDK组件,SDK组件包括API和工具链 list、install、uninstall、version、help 单独从下面命令包工具中下载
ohsdkmgr OpenHarmony SDK命令行管理工具,支持查看、安装和卸载SDK组件,SDK组件包括API和工具链 list、install、uninstall、version、help 单独从命令包工具中下载
ohpm 鸿蒙生态三方库的包管理工具,支持OpenHarmony共享包的发布、安装和依赖管理 init、install、uninstall、list、info、update、publish、ping /Users/xxx/Library/Huawei/ohpm/bin 注意运行该命令前需要先执行 bin 目录下的 init
☑️hdc HarmonyOS Device Connector,是HarmonyOS为开发人员提供的用于调试的命令行工具,和 adb 类似,开发者最常使用的工具 命令太多,详见链接 /Users/xxx/Library/Huawei/Sdk/hmscore/3.1.0/toolchains
hvigor 自动化构建工具 进程、性能等命令,不常使用 依赖工程目录下的 hvigorw 文件运行,暂不支持全局命令行
☑️bytrace 用于追踪进程轨迹、分析性能的一种工具,主要对内核ftrace进行了封装和扩展,来支持用户态的打点。通过该工具可以打开想要查看的用户态和内核label,然后通过命令行进行抓取trace信息到指定文件中。(类似 Android systrace) -t/--trace_begin/--trace_dump/--trace_finish/-l/-o/-z 执行 hdc shell(在 鸿蒙 4.0.0 真机上不好使)
codelinter 执行代码检查与修复 -c(指定执行检查规则配置文件)/-s(指定执行检查的工程根目录)/-f(检查的同时执行QuickFix)/-o(检查结果输出路径)/-v(查看版本)/-h(帮助) 单独从下面命令包工具中下载

鸿蒙贴心地提供了 codelinter、ohpm、sdkmgr 三个工具的工具包(点这下载),将该包配置到环境变量中,即可快捷使用。

注意:sdkmgr 仅支持 17+ 的 JAVA 版本。否则无法使用

问题

问题一:ERROR: Cannot find module 'node:path'

原因分析:

还记得前面提到的安装编译环境时,对 node.js 和 npm 版本是有要求的,然而我根据它的提示信息下载 node v15.14.0版本,还是会报错,需要升级到 node v16.20.2 及以上版本,不得不说,确实「坑」,提示信息不准确。

解决:

重新下载新的 node 包安装后 Rebuild project。

问题二:Failure[MSG_ERR_INSTALL_FAILED_NO_BUNDLE_SIGNATURE]

原因分析:

即使是 debug 模式下,也需要有包签名信息,不然无法运行到真机上

解决:打开 「Project Structure」,在登录华为开发者账号后自动生成一个签名。(吐槽:在 DevEco 上增加了一个登录按钮,要登录却还是跳转到了浏览器网页去进一步验证,做的不够彻底和统一)

在生成签名后,会发现在工程的 build-profile.json5 文件夹里就自动生成了相关的签名文件和签名信息:

问题三:Demo 在 鸿蒙 4.0.0 系统上出现卡死、黑屏问题

原因分析:

可能存在 app 4.0.0 系统和 3.x.x API 不兼容的情况。因为在 3.1.0 的模拟器上,Demo 是可以正常使用的,当然由于测试设备有限,无法明确定位到是这个问题。

解决:

暂时无法解决,后续跟进更新

问题四:当 PC 上同时打开 Android Studio 和 DevEco IDE 时,连接鸿蒙手机,有可能出现两个 IDE 都会识别不到设备的情况

原因分析:端口冲突?

解决:

关掉一个 IDE,重新插拔即可

与 Android Studio 异同

从我们上面几个章节的介绍,或多或少可以总结出一些 Android 和 鸿蒙 在构建工具方面的异同点出来:

  1. 都是基于 IntelliJ 改造后适用于 Android 和 Harmony 开发的 IDE,降低 Android 开发者迁移门槛

  2. 构建编译流程上,从代码构建、签名生成、打包属于同一类流程,即使是一些应用资源分布和代码构建,都能看到 Android 的影子

  1. 开发语言的不同(ArkTS vs Java/Kotlin),工具也从 Android 的 ADB 变成了 HDC(HarmonyOS Device Connector,两者命令对比可见下表)

  2. 构建工具从 Android 的 gradle/groovy 变成了 hvigor/json5(一款全新基于 TS 实现的前端构建任务编排工具,结合 npm 包管理机制,主要提供任务管理机制,任务注册编排、工程模型管理、配置管理等关键能力,更符合 ArkTS/JS 开发者的开发习惯) 的组合

  3. 编码风格和工程结构编排上也略有差异

HDC ADB 说明
hdc -h adb --help 查看帮助
hdc -v adb --version 查看版本
hdc list targets adb devices 查看连接设备
hdc kill adb kill-server 结束服务
hdc kill -r adb start-server 启动服务
hdc app install [安装包路径] adb install [安装包路径] 安装应用
hdc app uninstall package adb uninstall package 卸载应用
hdc hilog adb logcat 抓取log
hdc shell hilogcat >log.log adb shell logcat >log.log 抓取log并保存
hdc shell reboot adb reboot 重启设备
hdc shell bm get -u adb shell bm get -u 获取UUID
hdc file recv REMOTE... LOCAL adb pull REMOTE... LOCAL 接收文件<br />REMOTE:手机<br />LOCAL:PC
hdc file send LOCAL... REMOTE adb push LOCAL... REMOTE 发送文件
hdc shell screencap filename adb shell screencap filename 截屏
hdc shell screenrecord filename adb shell screenrecord filename 录屏

总结

该篇文章通过 IDE 以及构建过程,对一些鸿蒙相关的开发语言、构建环境、命令工具等基本概念进行了解释,为后续进一步开发打下基础。同时,在整个过程中,我们简单对比 Android 系统,发现鸿蒙现有的开发环境还有待改进,比如对命令工具需要单独下载配置、IDE Previewer 极耗 CPU、应用对系统兼容性等问题。

作者:ES2049 / 拂晓

文章可随意转载,但请保留此 原文链接

非常欢迎有激情的你加入 ES2049 Studio,简历请发送至 caijun.hcj@alibaba-inc.com

相关推荐
廖子默1 分钟前
提供html2canvas+jsPDF将HTML页面以A4纸方式导出为PDF后,内容分页时存在截断的解决思路
前端·pdf·html
光影少年33 分钟前
react和vue图片懒加载及实现原理
前端·vue.js·react.js
AndyGoWei35 分钟前
react react-router-dom history 实现原理,看这篇就够了
前端·javascript·react.js
小仓桑38 分钟前
深入理解 JavaScript 中的 AbortController
前端·javascript
摸鱼也很难40 分钟前
解决 node.js 执行 npm下载 报无法执行脚本的错
前端·npm·node.js
换个名字不能让人发现我在摸鱼41 分钟前
裁剪保存的图片黑边问题
前端·javascript
PeterJXL43 分钟前
pnpm:包管理的新星,平替 npm 和 yarn
前端·npm·node.js·pnpm
小牛itbull44 分钟前
Mono Repository方案与ReactPress的PNPM实践
开发语言·前端·javascript·reactpress
黑色的糖果1 小时前
vue2封装自定义插件并上传npm发布及使用
前端·npm·node.js