ArkTS 方舟编程语言 · 原创快速入门教程

适用读者:有 JavaScript / TypeScript 基础,想系统入门 ArkTS 与 HarmonyOS 应用开发的开发者。

本教程聚焦五个核心模块:ArkTS 语言本身 → 基础类库 → 并发机制 → 运行时 → 编译工具链,帮助你建立从"写代码"到"代码如何在设备上跑起来"的完整认知。


目录

  • 第〇章 在开始之前:ArkTS 是什么,它从哪来
  • 第一章 ArkTS 语言基础与类型系统(从 TypeScript 到 ArkTS)
  • 第二章 ArkTS 基础类库(容器、Buffer、XML、类型工具)
  • 第三章 ArkTS 并发编程(TaskPool、Worker、Sendable)
  • 第四章 ArkTS 运行时(ArkCompiler Runtime)
  • 第五章 ArkTS 编译工具链
  • 第六章 综合实践与学习路径

第〇章 在开始之前:ArkTS 是什么,它从哪来

0.1 一句话定位

ArkTS 是 HarmonyOS(鸿蒙)官方主力应用开发语言,它在 TypeScript 生态基础上做了扩展,同时强化了静态类型检查与并发能力,并配合 ArkUI 框架提供声明式 UI 开发能力。

0.2 三者的关系:JavaScript → TypeScript → ArkTS

复制代码
JavaScript  (动态、弱类型,运行时才暴露错误)
    ↑ 超集
TypeScript  (加了静态类型,编译期检查,但仍兼容宽松写法)
    ↑ 扩展 + 强化约束
ArkTS       (强制静态类型、更严格的语义约束、声明式UI、增强并发)

关键理解:

  • ArkTS 兼容 TypeScript 的语法风格 ,所以你会看到 let / const / class / interface / 箭头函数等熟悉的写法。
  • ArkTS 比 TypeScript 更严格。它主动禁用了许多"灵活但危险"的特性,换取程序运行时的稳定性和性能。
  • ArkTS 还 forward 扩展了 TypeScript 没有的能力:声明式 UI 装饰器、状态管理、并发任务 API

0.3 你需要准备什么

工具 作用
DevEco Studio 鸿蒙官方 IDE,内置 SDK、模拟器、调试器
HarmonyOS SDK 编译运行所需的系统库
真机或模拟器 运行与调试(注意:并发与基础类库部分能力模拟器暂不支持)

⚠️ 重要提示:截至当前版本,ArkTS 基础库与并发能力在模拟器上暂不支持,需要使用真机调试这部分内容。


第一章 ArkTS 语言基础与类型系统

1.1 强制静态类型

TypeScript 虽然支持类型标注,但你可以随意写 anyunknown,编译后类型信息就丢失了。ArkTS 反其道而行:

typescript 复制代码
// ArkTS:必须显式标注类型,禁止隐式 any
let name: string = "HarmonyOS";   // ✅ 必须写类型
const version: number = 6.0;      // ✅ 常量也要类型

// ❌ 以下在 ArkTS 中不被允许:
// let x = "hello";        // 隐式类型推导虽然可用,但推荐显式标注
// let y: any = 123;       // any 类型被禁用(部分宽松模式除外)

强制静态类型的收益:由于所有类型在程序运行前就已知,编译器可以在开发期验证代码正确性,减少运行时类型检查,从而提升性能与稳定性------这正是 ArkTS "为高性能而生"的设计哲学。

1.2 与 TypeScript 的关键差异(入门必读)

这是初学者最容易踩坑的地方。ArkTS 为了性能和稳定性,主动禁用了 TS 的若干特性:

特性 TypeScript ArkTS 说明
any / unknown ✅ 支持 ❌ 基本禁用 避免类型逃逸
var 关键字 ✅ 支持 ❌ 禁用 统一用 let / const
对象字面量声明类型 ✅ 支持 ❌ 禁用 需先定义类/接口
运行时改变对象布局 ✅ 允许 ❌ 禁止 不能运行时增删属性
结构化类型(Structural Typing) ✅ 支持 ❌ 不支持 采用名义类型(Nominal Typing)
in 运算符 ✅ 支持 ❌ 禁用
生成器函数 function* ✅ 支持 ❌ 禁用 async/await 替代
参数解构 ✅ 支持 ❌ 禁用 需显式传参
函数内声明函数 ✅ 支持 ❌ 禁用 用 lambda 代替
new.target ✅ 支持 ❌ 禁用
call/apply/bind 改 this ✅ 支持 ❌ 禁用
一元加法 + 作用于非数字 ✅ 允许 ❌ 禁止 限制运算符语义

关于"结构化类型":TypeScript 里只要两个对象"长得一样"就认为类型兼容。ArkTS 不支持这种写法,要求类型必须有明确的声明(名义类型)。

关于"对象布局不可变" :ArkTS 要求对象创建后不能随便添加/删除属性。比如 obj.newProp = 1 这种动态加属性的写法是不允许的。

1.3 类属性必须显式初始化

typescript 复制代码
class User {
  // ❌ ArkTS 不允许声明但不初始化(除非在构造函数中赋值)
  // name: string;

  // ✅ 正确:声明时初始化
  name: string = "";
  age: number = 0;

  // ✅ 或者在构造函数中初始化
  id: number;
  constructor(id: number) {
    this.id = id;
  }
}

1.4 声明式 UI 装饰器(ArkTS 的标志性能力)

ArkTS 最大的扩展是声明式 UI。它用"装饰器"来赋予类和变量特殊含义:

typescript 复制代码
@Entry          // 标记这是一个页面入口组件
@Component      // 标记这是一个可复用的 UI 组件
struct Index {
  @State message: string = 'Hello World'  // 状态变量:变化会驱动 UI 刷新

  build() {
    Column() {
      Text(this.message)
        .fontSize(24)
      Button('点击我')
        .onClick(() => {
          this.message = 'Hello ArkUI'  // 状态变化 → UI 自动更新
        })
    }
  }
}
装饰器 作用
@Entry 标识页面入口组件
@Component 标识自定义 UI 组件
@State 组件内部状态,变化触发 UI 重绘
@Prop 父组件向子组件单向传值
@Link 父子组件双向同步

声明式 UI 的核心思想:你描述"UI 应该长什么样"(基于当前状态),而不是写一堆"如何一步步修改 DOM"的命令。状态变了,UI 自动跟着变。

1.5 面向对象:类、接口、枚举

ArkTS 完整支持面向对象:

typescript 复制代码
// 接口
interface Shape {
  area(): number;
}

// 枚举
enum Color { Red, Green, Blue }

// 类 + 继承 + 实现接口
class Circle implements Shape {
  radius: number = 0;
  constructor(r: number) {
    this.radius = r;
  }
  area(): number {
    return 3.14159 * this.radius * this.radius;
  }
}

const c: Circle = new Circle(5);
console.info(`面积 = ${c.area()}`);  // 面积 = 78.53975

1.6 控制流与函数

typescript 复制代码
// 条件
let score: number = 85;
if (score >= 90) {
  console.info("优秀");
} else if (score >= 60) {
  console.info("及格");
} else {
  console.info("不及格");
}

// 循环
for (let i: number = 0; i < 5; i++) {
  console.info(`第 ${i} 次`);
}

// 函数(箭头函数也支持,但函数内不能嵌套声明函数)
const add = (a: number, b: number): number => a + b;

第二章 ArkTS 基础类库

ArkTS 基础类库增强了语言的基础功能,提供高精度浮点运算、二进制 Buffer、XML 生成解析转换,以及多种容器库等能力,帮助你减少重复造轮子。

2.1 容器类库:为什么需要它

普通的 TypeScript 数组 [] 固然好用,但在高性能场景下不够"讲究"。ArkTS 容器类采用类似静态语言的方式实现,并通过约束存储位置和属性,让每种数据类型去除冗余逻辑、保证高效访问

ArkTS 提供线性容器非线性容器两大类,共 14 种。

2.2 线性容器(按数组/链表实现)

线性容器实现能按顺序访问的数据结构。底层主要通过数组实现,运行时(Runtime)可通过一条字节码指令完成增、删、改、查。

容器 底层 特点与适用场景
ArrayList 动态数组(连续内存) 频繁读取元素时推荐;初始容量 10,每次扩容 2 倍
Vector 动态数组 比 ArrayList 多了一套 get/set 校验接口(API 9 后不再维护,推荐用 ArrayList)
List 单向链表(内存可不连续) 频繁插入/删除时推荐
LinkedList 双向链表 需要双向遍历的场景
Deque 双端队列 两端都可高效插入/删除
Queue 队列(基于链表) 任务调度、消息队列、缓存(先进先出)
Stack 栈(连续内存) 后进先出(LIFO)场景

注意:List 的修改不要用 list[index] = element 这种方式(会导致未定义结果),应使用 list.set(index, element)

代码示例:ArrayList

typescript 复制代码
import { ArrayList } from '@kit.ArkTS';

let list: ArrayList<string> = new ArrayList();
list.add("apple");
list.add("banana");
console.info(`长度: ${list.length}`);        // 长度: 2
console.info(`第0个: ${list[0]}`);           // 第0个: apple(支持 [] 访问)
console.info(`是否包含: ${list.has("apple")}`); // 是否包含: true
list.removeByIndex(0);
console.info(`删除后长度: ${list.length}`);   // 删除后长度: 1

代码示例:Stack 与 Queue

typescript 复制代码
import { Stack, Queue } from '@kit.ArkTS';

// 栈:后进先出
let stack: Stack<number> = new Stack();
stack.push(1);
stack.push(2);
console.info(`${stack.pop()}`);  // 2

// 队列:先进先出
let queue: Queue<string> = new Queue();
queue.add("task1");
queue.add("task2");
console.info(`${queue.getFirst()}`);  // task1

2.3 非线性容器(哈希/树实现)

非线性容器包括 HashMapHashSetTreeMapTreeSetPlainArrayLightWeightMapLightWeightSet 等,用于键值对存储、去重、有序集合等场景。

代码示例:HashMap

typescript 复制代码
import { HashMap } from '@kit.ArkTS';

let map: HashMap<string, number> = new HashMap();
map.set("Alice", 90);
map.set("Bob", 85);
console.info(`Alice 的分数: ${map.get("Alice")}`); // Alice 的分数: 90
console.info(`是否包含 Bob: ${map.hasKey("Bob")}`);  // 是否包含 Bob: true

2.4 其他基础能力

ArkTS 基础库还提供:

  • Buffer(二进制 Buffer):处理字节数据,常用于文件、网络、编解码。
  • XML 生成/解析/转换:将对象与 XML 互转。
  • 高精度浮点运算:金额、科学计算等需要精度的场景。
  • 类型工具 @arkts.lang :提供 ISendable 等接口(详见第三章 Sendable)。

2.5 如何选择容器(经验法则)

复制代码
需要按顺序、频繁随机访问?
  → ArrayList(数组) / LinkedList(频繁插入删除)
需要先进先出?
  → Queue
需要后进先出?
  → Stack
需要键值对?
  → HashMap
需要去重集合?
  → HashSet

第三章 ArkTS 并发编程

3.1 为什么需要并发

主线程(UI 线程)负责渲染界面。如果在主线程做耗时操作(大文件读写、复杂计算、图片滤镜),界面就会卡顿甚至卡死。

并发的目标:把耗时任务搬到其他线程执行,让 UI 始终保持流畅。

ArkTS 把并发分为两类:

类型 本质 代表技术
异步并发 单线程内通过事件循环"看起来同时"执行,并非真多核 Promise / async / await
多线程并发 真正利用多核,多个线程同时执行 TaskPool / Worker

简单类比:异步并发像"一个司机快速切换开两辆车";多线程并发像"两个司机各开各的车"。

3.2 Actor 模型:无锁的并发

ArkTS 的 TaskPool 和 Worker 都基于 Actor 并发模型

核心思想:线程之间不共享内存,也不使用锁。每个线程是一个独立的"房间",房间之间只能通过"发消息"传递数据(数据会被复制过去)。

  • ✅ 优点:天然无锁,杜绝死锁和竞态条件,系统更稳定。
  • ⚠️ 代价:数据传递有拷贝成本,需关注传输方式(详见 3.7 Sendable)。

3.3 TaskPool:任务池(官方推荐首选)

TaskPool 是在 Worker 之上的高层封装,帮你自动管理线程池。你只需把任务丢进去,系统负责调度、负载均衡、扩缩容。

核心特性

  • 系统自动管理线程池(最大约 64 个工作线程,随负载扩缩容)。
  • 支持任务优先级、任务取消、任务组(TaskGroup)。
  • 同步代码执行上限约 3 分钟(异步 I/O 如网络下载、文件读写不限时)。
  • 结果通过 Promise 异步返回。
3.3.1 @Concurrent 装饰器

TaskPool 执行的并发函数必须用 @Concurrent 装饰,否则编译不通过。

规则:

  • ✅ 只能修饰全局函数(普通函数或 async 函数)。
  • ❌ 不能修饰:箭头函数、generator、类成员方法、匿名函数。
  • ❌ 函数内禁止使用闭包变量(只能用入参、local 变量、import 引入的变量)。
typescript 复制代码
import taskpool from '@kit.ArkTS';

// ✅ 正确:全局函数 + @Concurrent
@Concurrent
function computeSum(n: number): number {
  let total: number = 0;
  for (let i: number = 0; i < n; i++) {
    total += i;
  }
  return total;
}

async function runTask(): Promise<void> {
  // 1. 创建任务
  let task: taskpool.Task = new taskpool.Task(computeSum, 1000000);
  // 2. 执行并等待结果
  let result: number = await taskpool.execute(task) as number;
  console.info(`计算结果: ${result}`);
}

// 调用
runTask();
3.3.2 任务组与优先级
typescript 复制代码
import taskpool from '@kit.ArkTS';

@Concurrent
function heavyWork(id: number): string {
  return `任务${id}完成`;
}

async function runGroup(): Promise<void> {
  let group: taskpool.TaskGroup = new taskpool.TaskGroup();
  group.addTask(new taskpool.Task(heavyWork, 1));
  group.addTask(new taskpool.Task(heavyWork, 2));

  // 设置优先级并执行任务组
  let results: Array<string> = await taskpool.execute(group, taskpool.Priority.HIGH) as Array<string>;
  console.info(`结果: ${JSON.stringify(results)}`);
}
3.3.3 任务执行中向宿主线程发消息
typescript 复制代码
@Concurrent
function taskWithProgress(): void {
  for (let i: number = 0; i < 100; i++) {
    // 向宿主线程发送进度
    taskpool.Task.sendData({ progress: i });
  }
}

// 宿主线程监听
let task: taskpool.Task = new taskpool.Task(taskWithProgress);
task.onReceiveData((data: object) => {
  console.info(`进度: ${(data as { progress: number }).progress}`);
});
await taskpool.execute(task);
3.3.4 适用场景
  • 大量或调度点分散的独立任务。
  • 运行时间 ≤ 3 分钟的 CPU 密集型任务。
  • 不需要常驻的"一次性"计算。

3.4 Worker:常驻后台线程

Worker 更接近传统多线程:是一个功能完备的独立线程,但需要你手动管理它的生命周期(创建、通信、销毁)。

基本用法

typescript 复制代码
// 1. 创建 Worker(指定脚本路径)
import { worker } from '@kit.ArkTS';
let w: worker.ThreadWorker = new worker.ThreadWorker("entry/ets/workers/MyWorker.ets");

// 2. 主线程接收消息
w.onmessage = (e: MessageEvents) => {
  console.info(`收到结果: ${e.data}`);
};

// 3. 主线程发送消息
w.postMessage("开始计算");

// 4. 销毁(务必手动释放!)
// w.terminate();
typescript 复制代码
// MyWorker.ets(Worker 线程脚本)
import { worker } from '@kit.ArkTS';
const parent: worker.ThreadWorker = worker.workerPort;

parent.onmessage = (e: MessageEvents) => {
  let result: number = (e.data as number) * 2;
  parent.postMessage(result);  // 回传结果
};
3.4.1 适用场景
  • 运行时间 超过 3 分钟的任务(如后台 1 小时的模型训练)。
  • 需要常驻、有状态、持续处理消息的线程。
  • 对线程生命周期需要精细控制的场景。

3.5 TaskPool vs Worker 对比

维度 TaskPool Worker
抽象层级 高层封装(基于 Worker) 底层线程
生命周期 系统自动管理 开发者手动管理
参数传递 直接传参、直接收返回值 需自行 postMessage 封装
优先级 ✅ 支持 ❌ 不支持
任务取消 ✅ 支持 ❌ 不支持
执行时限 同步代码 ≤ 3 分钟 不限
最大线程数 系统自动(约 64) 手动(最多约 64)
推荐度 ⭐ 首选 特定长任务场景

经验法则:能用 TaskPool 就用 TaskPool;只有当任务需要长时间常驻或精细线程控制时,才用 Worker。

3.6 Sendable:跨线程共享对象(进阶重点)

默认情况下,线程间传递对象是序列化拷贝(深拷贝)------数据被复制一份传过去,两边互不影响。但这有两个痛点:

  1. 大数据传输慢:传 100KB 以上的数据,拷贝成本高。
  2. 方法会丢失:普通对象拷贝后,其携带的成员方法会丢失。

ArkTS 提出的 Sendable 机制解决了这个问题:用 @Sendable 装饰的类,跨线程传递时是引用传递(多个线程指向同一个对象),存放在共享堆(SharedHeap)中,且方法不丢失。

typescript 复制代码
import { taskpool } from '@kit.ArkTS';

// 用 @Sendable 标记可共享类
@Sendable
class SharedCounter {
  count: number = 0;
  increment(): void {
    this.count++;
  }
}

@Concurrent
function workOnCounter(counter: SharedCounter): void {
  counter.increment();
}

async function demo(): Promise<void> {
  let counter: SharedCounter = new SharedCounter();
  let task: taskpool.Task = new taskpool.Task(workOnCounter, counter);
  await taskpool.execute(task);
  // 由于是引用传递,counter 的修改在宿主线程可见
  console.info(`count = ${counter.count}`);
}

@Sendable 的约束(很重要):

  • 只能写在 .ets 文件中。
  • 成员属性必须是 Sendable 类型或基础类型(string / number / boolean)。
  • 成员属性必须显式初始化。
  • 成员函数不能使用闭包,只能用入参、this 成员或 import 变量。
  • 只允许 Sendable 类继承 Sendable 类。
  • 导出 Sendable 类的文件,不能导出非 Sendable 属性。

⚠️ 线程安全警告 :Sendable 对象是引用共享的,多个线程同时修改会发生数据竞争。如果多线程并发访问,需要开发者自己加同步机制(如锁)保证安全。

引用传递 vs 拷贝传递如何选择

方式 适用场景
引用传递(@Sendable) 大数据(>100KB)、需要保留方法、多线程共享同一份数据
拷贝传递(普通对象) 数据量小、线程间需要独立副本、互不干扰

第四章 ArkTS 运行时(ArkCompiler Runtime)

4.1 ArkCompiler 的两大部分

ArkCompiler(方舟编译运行时)负责 ArkTS / TS / JS 的编译与运行,分为:

复制代码
ArkCompiler
├── ArkTS 编译工具链  (开发侧:把高级语言编译为 .abc 字节码)
└── ArkTS 运行时      (设备侧:加载并运行 .abc 字节码,执行程序逻辑)

本章讲运行时:代码到了设备上,是怎么被执行的。

4.2 运行时由哪些模块组成

方舟 ArkTS 运行时(ARK TypeScript Runtime)是一个完整的执行环境,包含:

复制代码
ArkTS 运行时
├── 对象分配器 + 垃圾回收器 (GC)     ← 管内存
├── 符合 ECMAScript 规范的标准库     ← 管语言内置能力
├── ARK 字节码解释器                ← 解释执行 .abc
├── 内联缓存 (Inline Cache)         ← 加速属性访问
├── 静态类型编译器                  ← AOT 编译加速
└── NAPI (C/C++ 函数接口)           ← 跨语言桥接

4.3 执行模式:AOT / JIT / 解释执行

ArkTS 运行时可以把字节码以多种方式执行:

模式 说明 特点
解释执行 逐条解释字节码 启动快,但运行慢
JIT(即时编译) 运行时把热点代码编译为机器码 兼顾启动与运行,但运行时有编译开销
AOT(提前编译) 打包前就把代码编译为机器码 运行时最快、最稳定,启动略慢

ArkTS 的一大优势是编译前置:相比传统 JS "运行时才编译",ArkCompiler 在开发/打包阶段就完成大量编译工作,既提前暴露错误,又提升运行时性能。

4.4 垃圾回收:HPP GC(高性能部分 GC)

GC(垃圾回收)自动管理内存,开发者不用手动 free。ArkTS 运行时采用 HPP GC(High Performance Partial Garbage Collection),特点:

分代模型:把内存按对象存活时间分区:

内存区 存放内容
年轻代 (Young) 新创建、存活率低的短命对象
老年代 (Old) 存活时间长的对象
大对象空间 (HugeObject) 大数组等大对象
只读空间 (ReadOnly) 字符串常量等只读数据
不可移动空间 (NonMovable) 系统类对象
机器码空间 (MachineCode) 编译后的机器码

回收算法

  • Young GC(年轻代回收):用 Copying(复制)算法------把存活对象复制到另一半区,直接回收旧半区。速度快,但回收空间有限。
  • Old GC(老年代回收):用 Sweep(清扫)+ Compact(压缩)算法,回收空间多,但耗时较长。

前台/后台优化

  • 前台(应用可见):优先保证流畅,减少 GC 停顿。
  • 后台(应用切到后台):触发 压缩 GC(CompressGC),同时整理年轻代和老年代,趁用户看不见时把内存彻底压缩。

对开发者的启示:理解 GC 能帮你避免"内存抖动"------比如不要在循环里疯狂创建临时大对象,会给 Young GC 造成压力。

4.5 NAPI:ArkTS 与 C/C++ 的桥梁

有些场景必须用 C/C++(游戏引擎、物理模拟、底层编解码)。HarmonyOS 提供 Node-API(NAPI),它是 ArkTS/JS 与 C/C++ 跨语言调用的接口。

典型用法:

  • 系统把底层模块能力通过 NAPI 封装成 ArkTS 接口开放给应用。
  • 开发者把性能敏感的核心逻辑用 C/C++ 实现,再用 ArkTS 接口调用。

4.6 内存模型:LocalHeap vs SharedHeap

回顾第三章的 Sendable,它在内存层面体现为一个关键设计:

复制代码
LocalHeap    (私有堆):普通 ArkTS 对象,每个线程独享
   ↑ 线程隔离,传递时拷贝

SharedHeap   (共享堆):@Sendable 对象,多线程共享同一份
   ↑ 引用传递,需注意线程安全

正是这个双堆设计,让 ArkTS 既保持了 Actor 模型的线程隔离(稳定),又通过 Sendable 支持了高效的大数据共享(性能)。


第五章 ArkTS 编译工具链

5.1 工具链做了什么

编译工具链运行在开发侧(你的电脑上),核心职责是:

把 ArkTS / TS / JS 高级语言,编译为方舟字节码文件(*.abc),再打包到应用里。

设备侧的运行时(第四章)只负责执行 .abc,不需要再做重量级编译,因此启动快、运行稳。

5.2 编译流程:从 .ets.abc

复制代码
你的源码 (.ets / .ts)
      ↓
[ 1. 前端解析 ]  ts2abc 组件(方舟 JS 前端工具)
      ↓  类型检查、语法校验、适配 ArkTS 约束
[ 2. 生成中间表示 ]
      ↓
[ 3. 编译为方舟字节码 ]
      ↓
方舟字节码 (.abc)
      ↓
[ 4. 打包进 HAP/HSP ]
      ↓
安装到设备 → 运行时执行 .abc

其中 ts2abc 是方舟平台的关键前端组件,负责把 JavaScript/TypeScript 转换为方舟字节码。

5.3 开发期静态检查(提前暴露错误)

传统 JS 开发常见痛点是:代码写错了,要等到运行时才报错(用户已经点进去了)。

ArkTS 工具链在编译/打包阶段就做严格静态检查,把错误提前暴露在开发期。这也是为什么 ArkTS 强制静态类型、禁用 any------这些约束让编译器能"看得懂"你的代码,从而帮你查错。

复制代码
传统 JS:  写代码 → 运行 → ❌ 报错(用户已受影响)
ArkTS:    写代码 → ✅ 编译期拦截错误 → 运行(更稳)

5.4 Disassembler:反汇编工具

当遇到字节码相关问题时,可以用 Disassembler(ark_disasm).abc 反编译成可读的汇编指令,用于分析底层行为。

工具随 DevEco Studio SDK 发布,位置类似:

复制代码
DevEco Studio/sdk/default/openharmony/toolchains/ark_disasm.exe

命令示例:

bash 复制代码
ark_disasm input.abc output.txt

5.5 自定义字节码修改

高级场景(如字节码插桩、定制优化)可以在编译期修改 .abc。在 build-profile.json5 中配置 transformLib

json5 复制代码
{
  "buildOption": {
    "arkOptions": {
      "transformLib": "./custom_transform.so"
    }
  }
}

编译器会在指定时机加载这个动态库并执行其中的 Transform 方法,让你能读取并改写字节码。

5.6 DevEco Studio 与工程配置

  • build-profile.json5:模块级构建配置(含编译选项)。
  • module.json5:模块配置(声明权限、Ability)。
  • app.json5:应用全局配置。

这些文件构成了编译工具链的"输入参数",决定了代码如何被编译、打包。


第六章 综合实践与学习路径

6.1 把五块拼图拼起来

回顾一下,当我们写一段 ArkTS 代码时,背后发生的事:

复制代码
① 语言层  :你用 ArkTS(强制类型 + 装饰器)写 UI 与逻辑
      ↓
② 基础类库:用 ArrayList/HashMap 等容器高效组织数据
      ↓
③ 并发层  :用 @Concurrent + TaskPool 把耗时计算丢到子线程,
            用 @Sendable 在多线程间高效共享数据
      ↓
④ 编译工具链:ts2abc 把代码编译为 .abc,开发期静态检查提前查错
      ↓
⑤ 运行时  :设备上的 ArkCompiler 运行时解释/执行 .abc,
            GC 自动管理内存,NAPI 桥接底层能力

6.2 动手练习建议

  1. 基础 :写一个带 @State 的计数器页面(掌握声明式 UI + 状态驱动)。
  2. 容器 :用 ArrayList / HashMap 实现一个学生成绩管理系统。
  3. 并发 :用 @Concurrent + TaskPool 计算 1 到 100 万的累加,并观察主线程不卡顿。
  4. Sendable:对比"普通对象跨线程(拷贝)"与"@Sendable 对象(引用)"的差异。
  5. 深入 :用 Disassembler 反编译你的 .abc,看看字节码长什么样。

6.3 学习资源方向

  • 官方文档:华为 HarmonyOS 开发者联盟(ArkTS 指南、API 参考)。
  • 动手优先:ArkTS 的约束(禁 any、禁闭包等)只有在写代码时才会真正理解。
  • 真机调试:并发与基础类库的进阶能力必须用真机验证。

附录:常见误区速查

误区 正解
"ArkTS 就是 TypeScript" 是 TS 的超集 + 强化约束 + UI/并发扩展
"用 TaskPool 随便写个函数就行" 必须用 @Concurrent,且不能闭包、不能是类方法
"多线程就能直接共享变量" ArkTS 默认拷贝传递;要共享得用 @Sendable
"Worker 比 TaskPool 高级所以更好" TaskPool 是首选;Worker 仅用于长任务/精细控制
"GC 会自动管内存,随便 new" 仍要避免内存抖动,尤其在循环里
"模拟器能测一切" 基础库与并发在模拟器暂不支持,需真机

本教程为原创入门学习材料,基于华为官方文档与公开技术资料整理编写,旨在帮助初学者系统建立 ArkTS 知识体系。

相关推荐
β添砖java18 小时前
黑马Linux笔记
linux·运维·笔记
在水一缸19 小时前
当 AI 拥有了“核按钮”:深入解析 MCP 服务器与命令执行护栏
运维·服务器·人工智能·命令执行·智能体·ai安全·mcp
小时代的大玩家19 小时前
HarmonyOS新特性-沉浸光感在叠叠消小游戏中的落地实践
前端·harmonyos
大龄秃头程序员19 小时前
SwiftUI 实战:从零构建双引擎 LLM 聊天客户端(Ollama + DeepSeek)
架构
●VON19 小时前
鸿蒙 PC Markdown 编辑器错误处理:让失败可恢复而不是只弹提示
华为·架构·编辑器·harmonyos·鸿蒙
爱莉希雅&&&19 小时前
Prometheus高可用(alertmanager+node_exporter+grafana)
运维·服务器·grafana·prometheus
heimeiyingwang19 小时前
【架构实战】CI/CD流水线:从手动部署到一键上线
ci/cd·架构
增量星球19 小时前
《持续交付2.0系列六》业务需求协作管理
java·运维·自动化·devops·持续部署·持续集成
世人万千丶19 小时前
鸿蒙Flutter Icon与IconButton
flutter·华为·harmonyos·鸿蒙