一文了解鸿蒙HarmonyOS开发

561 阅读14分钟

本文作者:来自 MoonWebTeam 的 junfengchen 腾讯高级工程师

本文编辑:kanedongliu

纯中国血统的自主操作系统HarmonyOS(鸿蒙操作系统)在2024年得到了进一步加速,不久的将来我们很可能用到HarmonyOS应用,甚至开发HarmonyOS应用。通过阅读本文,你了解HarmonyOS的同时还能具备一定的HarmonyOS应用开发基础。对web前端开发人员来说,HarmonyOS应用开发的web技术栈也更友好,能从中扩宽视野、获知技术差异。

1、HarmonyOS简介

1.1、HarmonyOS是什么?

HarmonyOS(鸿蒙操作系统)是华为公司开发的一款面向全场景的分布式操作系统;它基于微内核设计,旨在实现不同终端设备之间的极速连接、能力互助和资源共享。

1.2、HarmonyOS发展背景

"中美竞争"大背景下的自主操作系统

深圳市支持开源鸿蒙原生应用发展2024年行动计划--政策法规

时间节点事件说明
2012年华为开始研发鸿蒙操作系统
2018年12月1日华为孟晚舟在加拿大被捕
2019年5月美国将华为列入实体清单,限制美企与华为合作
2019年8月9日HarmonyOS 1.0 正式发布主要面向物联网设备,如智能手表、智能家居等
2019年12月1日孟晚舟在加拿大转机时被扣留应美国要求逮捕孟晚舟,涉及伊朗合作
2020年5月15日美国对华为实施第一轮制裁禁止华为使用美国技术和软件设计、制造半导体产品
2021年6月2日HarmonyOS 2.0 正式发布HarmonyOS 正式进入手机等智能终端市场,并在Mate 40、P40、Mate 30等手机上逐步升级
2021年9月24日孟晚舟释放并返回中国孟晚舟与美国政府达成延期起诉协议,加拿大法院随后终止引渡程序
2022年7月27日HarmonyOS 3.0 正式发布带来更流畅、更安全的用户体验,并拓展至更多设备类型
2023年8月4日HarmonyOS 4.0 正式发布
2024年 Q4HarmonyOS Next自研鸿蒙内核,完全抛弃AOSP不再兼容安卓应用

1.3、HarmonyOS优势

  • 除了"政策"优势,华为自身也有较为雄厚的技术和市场优势

截止3月底,中国市场智能手机上使用时间超过99%的5000个应用全面迁移到鸿蒙原生操作系统的计划:已有4000多个应用明确迁移计划,不到1000个应用沟通中;覆盖生活、出行、金融、社交、生产力工具、影音娱乐、游戏等领域。

华为徐直军:打造鸿蒙原生应用生态是华为2024年最关键的事情_腾讯新闻

  • 物联网时代的后发优势

随着传统移动互联网增长见顶,万物互联时代正在开启,应用设备底座将正在从几十亿手机扩展到数百亿IoT设备。相比Android、IOS,后发的HarmonyOS应能更好的适配物联网场景。

  1. 单一设备延伸到多设备和协同能力(分布式协同)
  2. 厚重应用模式到轻量化服务模式(类小程序模式)
  3. 集中化分发到AI智慧分发(服务主动找人)
  4. 纯软件到软硬芯协同的 AI 能力(终端AI计算)
  • 应用开发技术栈的生态基础

HarmonyOS应用开发的web技术栈拥有庞大悠久的技术生态,能助力HarmonyOS高效的获取技术积累、开发人员储备。

2、HarmonyOS应用形态和开发优势

2.1、应用形态优势

相比Android、IOS,后发的HarmonyOS在应用形态的优势如下

  • 除了传统的安装式App,还从系统层面支持类小程序模式的即用即走元服务;且App、元服务是同一套技术栈、开发模式
  • 个人多设备的场景下(手机、平板、穿戴设备等),支持跨设备交互的连续性、状态同步等能力
  • 元服务还可基于场景和用户意图拉起元服务,实现"按需分发、服务直达"

img

2.2、应用开发优势

相比Android、IOS,HarmonyOS作为一款面向全场景的分布式操作系统,在应用开发的优势如下

2.2.1、分布式开发调试能力

相比Android、IOS开发套件,HarmonyOS的DevEco Studio是面向全场景多设备的一站式开发平台(分布式开发调试能力

img

  • 分布式调试:同一个应用跨设备交互的代码断点和调试
  • 分布式调优:多设备分布式调用的链路跟踪、调用堆栈、性能数据采集分析
  • 多端双向预览:UI 代码在多个设备上同时预览,并支持预览效果的双向定位修改
  • 超级终端模拟:支持并提供多个模拟终端、真机设备自由组合成超级终端,满足分布式调试环境

2.2.2、多端统一适配能力

相比Android、IOS编码体系,HarmonyOS在开发层面抹平了全场景多设备下的编码差异

  • 多端 UI 适配:如将不同设备的物理像素在系统底层抽象成虚拟像素(vp),使其具有一致的视觉体量 img (类比CSS像素px的效果)

  • 交互事件归一:抹平不同设备对用户输入的交互差异,提供开发者一致的事件处理。例缩放交互: img

  • 设备能力抽象:不同设备的软硬件能力差异(是否可定位、摄像头、蓝牙等),通过"系统能力"定义每个能力部件,为开发者提供统一的访问方式(类比前端统一的JSAPI)

--参考 系统能力SystemCapability列表

2.2.3、多端灵活分发能力

Hap:包含代码、资源、第三方库和配置文件的独立功能模块(应用功能模块化,每个Hap可独立安装)

App Pack:应用市场上架的应用软件包(通常由一个或多个Hap、pack.info描述信息组成)

  • 一个工程构建一个应用程序App Pack:每个功能模块Hap支持配置不同的兼容环境配置,实现应用程序内的Hap定向安装

img

// cjf_stage1/entry/build-profile.json5
{
  "apiType": 'stageMode',
  "buildOption": {
  },
  "targets": [
    {
      //未定义deviceType,默认支持config.json或module.json5中定义的设备类型
      "name": "default",
      "runtimeOS": "HarmonyOS"
    },
    {
      "name": "free",  //免费版名称
      "runtimeOS": "HarmonyOS" // OpenHarmony
      "config": {
        "deviceType": [  //定义支持的设备类型为phone
          "phone"
        ]
      },
      "source": {  //定义产物源码会用到的pages源码文件
        "pages": [
          "pages/index"
        ]
      },
      "resource": {  //定义产物资源使用的资源文件目录
        "directories": [
          "./src/main/resources_default",
          "./src/main/resources_free"
        ]
      }
    },
    {
      "name": "pay",  //付费版名称
      "runtimeOS": "HarmonyOS",
    }  
  ]
}
  • 一个工程构建多个应用程序App Pack:不同的功能模块或元服务按需组合成不同的App Pack(同一个App Pack下生命周期共享) img

2.3、AI能力集成

相比Android、IOS,后发的HarmonyOS在AI能力集成方面相信也会更完善,给到开发者一站式体验

img

3、HarmonyOS应用技术体系

img

上图展示HarmonyOS的整套应用开发体系;若有兴趣进一步了解如分布式服务、安全架构、硬件服务等,或者更详细的基础材料可参考 HarmonyOS开发者官网

下面对HarmonyOS应用开发的主要技术点展开

3.1、ArkTS 语言

如开篇提到的web技术栈,HarmonyOS应用的主开发语言ArkTS,正是基于TypeScript语法之上扩展了声明式UI、状态管理、并发控制等能力

img

下面对几个核心扩展、TS特性差异展开说明

  • 声明式UI(语法) img
  • 状态管理(数据驱动UI)

@StorageLink变量装饰器与AppStorage配合使用;类比Vue的Vuex状态管理,包括组件内的状态也类似Vue组件

差别是:变量必须被装饰器装饰才可以成为状态变量驱动UI刷新 img

@Component  // 声明一个组件
struct CountDownComponent {
  @Prop count: number;
  // 没有装饰器,不引起UI的渲染刷新
  test: number = 1;

  build() {
    Column() {
      Text(`You have ${this.count} Nuggets left`)
      // @Prop装饰的变量不会同步给父组件;使用@Link则能双向同步
      Button(`Try again`).onClick(() => { this.count -= this.test })
    }
  }
}

@Entry // 声明一个page入口
@Component
struct ParentComponent {
  // 组件内状态 
  @State countValue: number = 10;

  build() {
    Column() {
      // 父组件的数据源的修改会同步给子组件
      Button(`+1`).onClick(() => { this.countValue += 1 })
      
      CountDownComponent({ count: this.countValue, test: 2 })
    }
  }
}
  • 并发控制
  1. Promise和async/await提供异步并发能力,适用于单次I/O任务的开发场景
  2. TaskPool和Worker提供多线程并发能力,适用于CPU密集型任务、I/O密集型任务和同步任务等并发场景
  • TS特性差异(摒弃动态特性)
  1. 对象字面量必须标注类型
// ArkTS编译错误(缺少类型限制,编译器无法深度优化)
const point = { x: 0, y: 0 }
  1. 不支持TS structural type(结构化类型)
class One {
  public x: number = 10;
}

class Two {
  public x: number = 10;
  public y: number = 20;
}

function test(param: One) {
  console.log(param.x.());
}
// ArkTS编译错误,ArkTS仅支持nominal typing(命名类型)
test(new Two());

3.2、ArkUI 框架

提供应用UI开发所必需的能力,如多种组件、布局计算、动画能力、UI交互、绘制等;支持两种开发范式

开发范式名称语言生态UI更新方式适用场景适用人群
声明式开发范式ArkTS语言数据驱动更新复杂度较大、团队合作度较高的程序移动系统应用开发人员、系统应用开发人员
类Web开发范式JS语言数据驱动更新界面较为简单的程序应用和卡片Web前端开发人员

两种开发范式的UI后端引擎和语言运行时是共用的,但因为类Web开发范式基于div+css构建UI布局,需要加一层JS Framework进行Dom树生成解析,映射ArkUI组件树渲染(相对的渲染链路更长、占用内存更多)

img

注:JS Framework主要负责Dom树解析,包括MVVM数据驱动、自定义组件等处理

声明式开发范式

优势是声明式UI更简洁(不关心UI如何绘制和渲染)、性能更优(渲染链路较短)、官方主推支持

// 页面含有居中的文本、按钮,按钮点击路由至其他页面
import router from '@ohos.router';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  
  // @Entry装饰的组件才可以调用页面生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  
  // 组件生命周期
  aboutToAppear() {
    console.info('MyComponent aboutToAppear');
  }
  
  build() {
    // 线性布局
    Row() {
      Column() {
        Button() {
          Text('Next')
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
        }
        .type(ButtonType.Capsule)
        .margin({
          top: 20
        })
        .backgroundColor('#0D9FFB')
        .width('40%')
        .height('5%')
        .onClick(() => {
          router.pushUrl({ url: 'pages/Second' })
            .then(() => {
               console.info('success')
            }).catch((err) => {
               console.error(`Failed`)
            })
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

--参考 基于ArkTS的声明式开发范式

类web开发范式 优势是开发范式更契合web前端人员的编码体验;但"类"字表明了不等同于web开发,自身有一套开发约束 以html标签为例:除了标签的属性有差异,还提供了官方内置的高阶组件,如容器、媒体、画布等相关

// pages/index/index.html
<div class="container">
    // 自定义弹窗容器
    // ref 指向子元素或子组件,注册到父组件的$refs属性(类似Vue ref引用)
    <dialog id="dragDialog" ref="myDialog">
        <text class="title">
            {{ $t('strings.hello') }} {{ title }}
        </text>
    </dialog>
</div>
// pages/index/index.js
export default {
    data: {
        title: ""
    },
    onInit() {
        this.title = this.$t('strings.world');
    }
}

// pages/index/index.css
.container {
    display: flex;
    // ...
}
.title {
    font-size: 60px;
}
@media screen and (orientation: landscape) {
    .title {
        font-size: 60px;
    }
}

--参考 兼容JS的类Web开发范式

3.3、Ability概念

官方概述:

Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个Ability),HarmonyOS支持应用以Ability为单位进行部署。

UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。

从web前端开发的视角,终端应用相比浏览器的扁平式web界面,更像一个"小系统"。所以HarmonyOS在更上一层抽象了Ability概念,类比android的activity、service等组件体系

以UIAbility为例,可以包括一个或多个用户所看到的传统页面page。同时除了传统页面page的生命周期,UIAbility也有自身的生命周期,包括创建、销毁、切换至前台、切换至后台的状态。使用场景如:一个聊天程序中添加一个与聊天不相关的"直播功能"场景,那可以把直播功能的内容独立为一个UIAbility。

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';

export default class EntryAbility extends UIAbility {
  // 应用加载过程中,UIAbility实例创建完成时触发
  onCreate(want, launchParam) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  } 
  
  // UIAbility实例切换至后台时触发
  onBackground() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
  // ...
}

3.4、方舟编译器

方舟编译器(ArkCompiler)是HarmonyOS支持多种语言(ArkTS、TS、JS)、多种芯片平台的多设备统一编译&运行时底座

Javascript在web前端是解释型语言,但在HarmonyOS这属于编译型语言

img

方舟编译器主要分成两部分:编译工具链与运行时

  • 编译工具链:将ArkTS/TS/JS源码编译成ABC文件(ArkCompiler Bytecode方舟字节码)

img

  1. 解析:读取 ArkTS 源码,进行词法&语法解析生成抽象语法树(AST)
  2. 转换:识别语法糖,转换成基础语法
  3. 编译:根据抽象语法树,生成对应的中间表示(IR)
  4. 输出:收集 IR、字符资源、常量等各种元素,基于ABC文件格式生成字节码文件
  5. 优化:读取ABC文件的字节码信息生成 IR 表示,进行优化处理并重新生成
**混元理解**
ArkCompiler Bytecode(方舟字节码)是ArkCompiler编译器生成的一种硬件和平台无关的中间表现形式。
它采用基于寄存器的字节码格式,每个寄存器的宽度为64位,最多支持65536个寄存器。
ArkCompiler字节码的设计目标是紧凑、可扩展、多语言支持,以便屏蔽设备差异,支持应用的跨设备分发、部署和运行。
// 以下是一个简单的ArkCompiler字节码示例,用于计算两个整数的和:
function add(a: number, b: number): number {
    return a + b;
}
// 下面展示编译后的简化ABC指令集;实际还会包含更多的元数据和其他信息,以便运行时正确执行
function add(a: number, b: number): number {
    .locals 1
    iload a
    iload b
    iadd
    istore result
    iload result
    ireturn
}
  • 运行时:解析运行字节码文件,实现对应语言规范的语义逻辑
  1. 运行优化:编译TS源码的TS类型信息会分析并传给运行时,以此预生成内联缓存加速字节码执行
  2. 并发模型优化:相比Web/Node基于Actor 模型的Worker API;实现了不可变或不易变对象的共享(方法和字节码)
**混元理解**
Actor模型是一种并发编程模型。Actor模型的核心思想是将计算过程分解为一系列独立的、相互隔离的单元,即Actor。
每个Actor都是一个基本的计算单元,能够接收消息并基于消息执行计算,同时也可以发送消息给其他Actor。
Actor之间不共享内存,因此不存在相互调用的问题,只有消息通知。
Actor的数据状态完全由自己维护,这使得Actor模型具有容错性和分布式特点。

3. 除了业界通用的Worker API,还提供了TaskPool支持优先级调度、自动扩缩容 4. 仅支持严格模式JS代码,不支持如 eval 等 运行动态字符串

4、HarmonyOS应用开发实践

4.1、开发环境配置

标准版的DevEco Studio开发套件,安装过程按向导操作即可

--参考 DevEco Studio安装、环境配置与诊断(官方)

img 注:HarmonyOS Next版尚处于beta版,依赖开发者权限、手动配置开发套件等,较麻烦不展开(有兴趣可进一步了解)

4.2、开发调试

官方提供比较齐全的演示Demo,建议下载并试跑一下加深了解

--参考 HarmonyOS演示Demo

5、总结

移动互联网时代已有十多年了,在Androad、IOS之下突围的HarmonyOS有着物联网时代、"中国国情"的背景积累;包括相应的跨平台框架更是不间断的推陈出新。对于技术开发人员,与时俱进的了解当下技术热点是必要的

6、参考材料

最后,如果客官觉得文章还不错,👏👏👏欢迎点赞、转发、收藏、关注,这是对小编的最大支持和鼓励,鼓励我们持续产出优质内容。

点赞

7、关于我们

MoonWebTeam目前成员均来自于腾讯,我们致力于分享有深度的前端技术,有价值的人生思考。

8、往期推荐

MoonWebTeam前端技术月刊第2期

领域驱动设计之Domain Primitive

低码编辑器中的“拖拽”是如何实现的

一文带你了解AI程序员DEVIKA

前端依赖注入的探索和实践