你是不是也在想——“鸿蒙这么火,我能不能学会?”
答案是:当然可以!
这个专栏专为零基础小白设计,不需要编程基础,也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例,手把手带你从安装开发工具开始,一步步学会开发自己的鸿蒙应用。
不管你是学生、上班族、打算转行,还是单纯对技术感兴趣,只要你愿意花一点时间,就能在这里搞懂鸿蒙开发,并做出属于自己的App!
📌 关注本专栏《零基础学鸿蒙开发》,一起变强!
每一节内容我都会持续更新,配图+代码+解释全都有,欢迎点个关注,不走丢,我是小白酷爱学习,我们一起上路 🚀

前言

先抛三连击:电一来,BootLoader 先和谁打招呼?内核醒了都叫哪些兄弟起床?Launcher 的第一帧 UI 到底跨了多少“沟坎”?要是你也好奇“从黑屏到桌面”的神秘旅程,今天我们不卖关子,把鸿蒙(OpenHarmony/HarmonyOS)从通电到应用首屏的关键链路,以及模块(SystemAbility/HAP/HSP)加载机制,一口气掰开揉碎。没有玄学,只有工程学;没有“AI 味”,只有“人话 + 真代码”。🧰

目录(先剧透,少走弯路)

  1. 全局鸟瞰:从 0 到 1 的启动时间轴
  2. Boot 阶段:BootROM → BootLoader → Kernel
  3. 内核完工后的第一棒:init how-to
  4. 系统服务登场:SAMgr & SystemAbility 启停机制
  5. 应用运行时:appspawnBundleMgrAbilityMgr 到首个 UIAbility
  6. 模块加载四件套:HAP/HSP/Native so/Extension 的装配线
  7. ArkTS 侧“从包到页”的落地路径(含示例代码)
  8. 冷启动 vs 热启动:性能剖面与调优清单
  9. 故障“复盘手册”:起不来/起太慢/起错了怎么抄家伙
  10. 总结 & Checklist:上线前最后的自检项

1) 全局鸟瞰:一张时间轴,看懂“黑屏到桌面”

[通电/复位]
   ↓BootROM (SoC 固化)         — 验签/加载 BootLoader
   ↓BootLoader (BL1/BL2...)    — DDR/时钟/设备树/二阶引导/验签内核
   ↓Kernel 启动                — 早期 initcalls,挂载根,启动 PID=1
   ↓/init                      — 解析 init 配置,跑 early/late jobs,拉起核心服务
   ↓系统服务/SAMgr             — 注册与按需启动 SystemAbility(SA)
   ↓appspawn(应用孵化器)     — 派生应用进程,创建运行时(ArkTS/JS/Native)
   ↓BundleMgr/AbilityMgr       — 解析 HAP/HSP,路由到 EntryAbility
   ↓Launcher(UIAbility)        — ArkUI 渲染首帧

记一句话:init 是“服务剧场”的导演,SAMgr 是“演员经纪人”,appspawn 是“化妆师”,AbilityMgr 是“场记+调度”,ArkUI 是“舞台灯光”。


2) Boot 阶段:BootROM → BootLoader → Kernel(“把地基打牢”)

  • BootROM:SoC 内置,做的事极朴素——把 BootLoader 放上台(外设或片上存储),同时对镜像做基本验签。

  • BootLoader

    • 初始化时钟/DDR,搬砖设备树(或 BoardCfg);
    • 二阶引导(比如 BL2 → BL3),准备启动内核与 ramdisk;
    • 安全启动链:签名、测量、不可回滚;
  • Kernel

    • 设备驱动初始化(分阶段 initcalls);
    • 根文件系统挂载(ramdisk → 持久分区);
    • 拉起 PID=1 的 /init —— 戏肉马上开始

调优要点:串并行混排。BL 时做并行 I/O 预热,内核阶段启 initcall_debug 看谁拖了后腿。


3) /init:系统起家之本(“导演进场,分组开拍”)

鸿蒙/开源版常见的是 JSON/CFG 风格的 init 脚本(不同分支略有差异)。职责包括:

  • 解析启动图(services/jobs/triggers);
  • 挂载与权限(fs、dev、proc、sys);
  • 环境生产(系统属性、守护进程、套接字、用户/组);
  • 分阶段启动:core → system → late。

示例(伪示例,说明语义):

// init.cfg (示意)
{
  "jobs": [
    { "name": "early-init", "cmds": ["mount proc /proc proc", "mount sysfs /sys sysfs"] },
    { "name": "init",       "cmds": ["start core-services"] },
    { "name": "late-init",  "cmds": ["start system-services"] }
  ],
  "services": [
    { "name": "samgr", "path": "/system/bin/samgr", "class": "core", "oneshot": true },
    { "name": "appspawn", "path": "/system/bin/appspawn", "class": "core" },
    { "name": "bundlemgr", "path": "/system/bin/bms", "class": "system" },
    { "name": "abilitymgr", "path": "/system/bin/ams", "class": "system" }
  ],
  "on": [
    { "trigger": "boot", "jobs": ["early-init", "init", "late-init"] }
  ]
}

操作顺序关乎冷启动的“第一印象”:核心服务(samgr/appspawn)能早则早,非关键服务延后或懒启动。


4) SAMgr 与 SystemAbility:服务的“注册、发现、按需”

SystemAbility(SA) 是鸿蒙系统服务的标准单元。

  • 注册:服务进程把自家 SA 注册到 SAMgr
  • 发现:客户端通过 SA ID 找服务(本机或分布式);
  • 加载策略开机常驻 / 按需(lazy) / 条件加载(分布式/特性开关)

典型 C++ 代码(示意):

// MyFooService.h
class MyFooService : public SystemAbility, public FooStub {
    DECLARE_SYSTEM_ABILITY(MyFooService);
public:
    MyFooService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) {}
    void OnStart() override { /* init threads / load index */ }
    void OnStop() override { /* cleanup */ }
    // IPC methods...
};

// MyFooService.cpp
REGISTER_SYSTEM_ABILITY_BY_ID(MyFooService, 1520001, true); // true=开机即跑

好处

  • SA 解耦:IPC/IDL 边界清晰,便于团队协作与权限隔离;
  • 可懒可饿:不阻塞首屏,不浪费常驻内存;
  • 分布式:能力可向可信设备“外发”(受策略/ACL 控制)。

5) 应用运行时:appspawnBMSAMSUIAbility

  • appspawn:像 Android 的 zygote,预热运行时(ArkTS/JS/Native),接到孵化请求后派生新进程。

  • BMS(BundleMgr):解析与安装包(*.hap),维护 包、模块(module)、特性(feature) 索引;

  • AMS(AbilityMgr):管理 Ability 生命周期与任务栈;

  • 第一帧之路

    1. Launcher 的 Entry HAP 被 AMS 激活
    2. appspawn 派生进程,装载 HAP/HSP + JSVM/ArkTS
    3. 框架加载 EntryAbility,ArkUI 渲染 Root Page
    4. SurfaceFlinger 类合成(具体命名以平台版本为准)→ 点亮首帧

6) 模块加载四件套:HAP/HSP/Native so/Extension

  • HAP(Harmony Ability Package):应用的部署单元,包含 module.json5、资源、ArkTS/JS、Native so。
  • HSP(Harmony Shared Package)共享包,可以被多个 HAP 复用(类库/资源聚合,减少重复与更新成本)。
  • Native so:通过 libXYZ.so 提供性能/设备特定能力;
  • Extension:非 UI 的扩展点(ServiceExtension/Wallpaper/ArkWeb 等)。

module.json5Stage 模型示意):

{
  "module": {
    "name": "entry",
    "type": "entry",
    "srcEntry": "./ets/entryability/EntryAbility.ets",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": ["phone","tablet","wearable","tv"],
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntrance": "./ets/entryability/EntryAbility.ets",
        "label": "$string:app_name",
        "type": "page",
        "launchType": "standard",
        "visible": true
      }
    ],
    "dependencies": [
      { "shared": true, "name": "hsp.design.tokens" }  // 依赖 HSP
    ]
  }
}

7) ArkTS 从“包到页”:一条最短链 + 可观测点

7.1 EntryAbility 最小可跑骨架

// ets/entryability/EntryAbility.ets
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  async onWindowStageCreate(stage: window.WindowStage) {
    // 1) 加载首页
    stage.setUIContent('pages/Index'); // ArkUI 渲染树入口
    // 2) 埋点:首帧时刻
    console.info('[boot] FirstContentfulPaint@UIAbility');
  }
}

7.2 ArkUI 首页:首帧轻量化

// ets/pages/Index.ets
@Entry
@Component
struct IndexPage {
  @State ready: boolean = false;

  aboutToAppear() {
    // 异步加载二级资源,首帧只渲染骨架屏
    setTimeout(() => this.ready = true, 0);
  }

  build() {
    if (!this.ready) {
      // 骨架屏:避免白屏时间被拉长
      Column() {
        Text('Loading…').fontSize(18).opacity(0.6)
      }.width('100%').height('100%').justifyContent(FlexAlign.Center)
      return;
    }

    // 真正内容
    Column() {
      Text('Hello, Harmony!').fontSize(22).fontWeight(FontWeight.Bold)
    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
  }
}

实践金句首帧像“自我介绍”——一分钟道理、一秒钟做事。把重活延后,IO 与 CPU 交错;避免同步链拖垮 FCP。


8) 冷启动 vs 热启动:测、盯、调,少走弯路

8.1 关键里程碑(建议打点)

  • BOOT_START(上电/冷复位)
  • KERNEL_READY(init 启动)
  • SAMGR_READY / APPSPAWN_READY
  • BMS_READY / AMS_READY
  • ENTRYABILITY_ONCREATE
  • FIRST_FRAME_DRAWN(或 FCP)

8.2 常用加速手法

  • 服务分级启动class: core/system/late 合理分桶;能懒就懒
  • 按需加载 HSP:把大库放 HSP,按需链接;主 HAP 保持苗条。
  • 资源瘦身:首包去掉非首屏资源(大图片、字体子集化)。
  • 并行预热:IO 预读(相册/配置),CPU 解压并行(线程池)。
  • ArkTS/ArkUI:避免大对象在 build() 里分配;多用 @State 粒度更新;骨架屏优先
  • Native so:延迟 dlopen;热点路径上减少懒绑定开销。
  • IPC 合并:启动链路压 RPC 次数(一次问清,别“十连问”)。

9) 故障复盘手册:三板斧解决 80% 启动问题

  1. 起不来

    • init 日志:服务有没有被拉起?崩于权限/路径?
    • samgr 是否注册成功?SA ID 冲突?
    • appspawn 是否能派生?签名/沙箱权限是否缺项?
  2. 起太慢

    • 火焰图/trace:找“长同步链”。
    • BMS 解析大包/多包依赖:合并/拆分 HSP。
    • UI 首屏大量资源:切骨架屏 + 懒加载。
  3. 起错了

    • module.json5 是否 mainElement 填错、srcEntry 指向不一致?
    • 多入口(多 HAP)路由冲突:看 AMS 决策与调用栈。

10) 总结 & 上线前 Checklist(贴墙,真有用)

一句话总结启动像搭积木——Boot 把地基打牢,init 安排顺序,SAMgr 派角色,appspawn 生进程,BMS/AMS 把剧本递到 EntryAbility,ArkUI 打第一束光。
目标不是“全部最快”,而是“关键路径无阻塞、其余延后不伤体验”。

Checklist

  • init 配置三段式:early/core/system/late 分明
  • SA 清单:谁常驻、谁懒启动、谁条件加载
  • HAP/HSP 边界:首包苗条,HSP 复用重货
  • 首帧策略:骨架屏 + 异步资源 + IPC 合并
  • 埋点闭环:从 BOOT_STARTFIRST_FRAME 全链路
  • 故障预案:起不来/慢/错的定位脚本与回滚方案
  • 安全与合规:签名、权限声明、按需暴露能力

实操附录:几段能“落地”的小样

A. 注册一个按需加载的 SA(C++ 示意)

// On-demand SA,只有被访问才启动,避免冷启塞车
class MediaIndexService : public SystemAbility, public MediaIndexStub {
  DECLARE_SYSTEM_ABILITY(MediaIndexService);
public:
  explicit MediaIndexService(int32_t id) : SystemAbility(id, /*runOnCreate*/false) {}
  void OnStart() override { BuildIndexAsync(); }
  sptr<IRemoteObject> AsObject() override { return this; }
};
REGISTER_SYSTEM_ABILITY_BY_ID(MediaIndexService, 1609001, false); // false=懒启动

B. module.json5 里拆包依赖(HSP)

{
  "module": {
    "name": "entry",
    "type": "entry",
    "dependencies": [
      { "name": "hsp.media.core", "shared": true },
      { "name": "hsp.design.tokens", "shared": true }
    ]
  }
}

C. ArkTS 启动阶段的“同步链切断术”

// 把重 IO 从 onWindowStageCreate 拆走,改用微任务/idle
export default class EntryAbility extends UIAbility {
  async onWindowStageCreate(stage) {
    stage.setUIContent('pages/Index'); // 先点亮
    Promise.resolve().then(() => this.warmUp()); // 下一轮事件循环
  }
  private async warmUp() {
    // 预取配置、建立 IPC 通道、解压小字库...
  }
}

“就问你一句”🙃

**下一次你盯着黑屏数进度条,愿意把所有服务都塞进冷启动那 800ms 吗?**还是,按需、分级、瘦身、并行,让用户先看到第一束光?**启动不是魔法,是工程习惯。**我们今天把“习惯”摆上了台面。

进一步加码(你点我就补 💪)

  • 更细的 init 语法/触发器白皮书 + 实战样例
  • appspawn 进程模型与 ArkTS VM 预热细节
  • HSP 资源复用 与多 HAP 版本协同策略
  • 启动 Trace 模板(关键里程碑自动采集)与 火焰图 解读教程

❤️ 如果本文帮到了你…

  • 请点个赞,让我知道你还在坚持阅读技术长文!
  • 请收藏本文,因为你以后一定还会用上!
  • 如果你在学习过程中遇到bug,请留言,我帮你踩坑!
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐