HarmonyKit | HarmonyOS Kit 模块化体系与零依赖架构实践

HarmonyKit | HarmonyOS Kit 模块化体系与零依赖架构实践

引言:一行 import 就够了

在开发 HarmonyKit 的过程中,有一个细节让我印象很深:整个项目没有引入任何第三方 npm 包。Base64 编解码用了 @kit.ArkTS 下的 util 子模块,哈希计算用了 @kit.CryptoArchitectureKitcryptoFramework,剪贴板操作用了 @kit.BasicServicesKitpasteboard。三个系统 Kit,覆盖了所有需要的能力。

这让我想起了 Android 开发时期的"地狱依赖链"------Base64 需要引入 Apache Commons Codec,哈希计算需要引入 Bouncy Castle 或者至少一个工具库,剪贴板需要处理各种系统版本的兼容性差异。一个"简单的开发者工具箱"可能需要引入 5-8 个第三方库,每个库有自己的版本冲突、安全漏洞、许可证限制。

HarmonyOS 的 Kit 模块化体系从根本上改变了这个局面。这篇文章会详细讲解 HarmonyKit 项目中依赖的四个系统 Kit------它们各自提供了什么能力,在项目中的典型调用方式,以及为什么 Kit 体系使得"零第三方依赖"成为可能。

项目仓库:https://atomgit.com/VON-/harmony-kit

Kit 体系的核心理念

HarmonyOS 的 Kit 体系是一条根本性的设计原则:模块化系统能力的交付 。传统操作系统的 API 通常集中在少数几个巨大的命名空间下(比如 Android 的 android.* 包、iOS 的 UIKit/Foundation 框架)。HarmonyOS 选择将系统能力按功能域拆分为独立的 Kit(工具包),每个 Kit 有自己独立的命名空间、版本号、API 生命周期和废弃策略。

看看 HarmonyKit 的 import 语句就能感受到这种设计:

typescript 复制代码
import { util } from '@kit.ArkTS';
import { hdsMaterial, HdsTabs, HdsTabsController } from '@kit.UIDesignKit';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { pasteboard } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

每个 Kit 以 @kit.XxxKit 的方式导入。一行 import 精准地描述了这个文件依赖了哪些系统能力。没有全局对象(如 Android 的 Context),没有隐式权限(你需要什么就导入什么),没有跨 Kit 的意外耦合。

这种设计的核心好处有四个:

可审查性。看一个文件的 import 列表,就知道它使用了哪些系统能力。安全审查时,不需要逐行检查代码中是否隐藏地调用了网络请求或文件访问------import 列表就是能力清单。

按需加载。Kit 是懒加载的。应用启动时不会加载所有系统能力,只有在代码首次引用某个 Kit 时才会初始化。这减少了应用冷启动时间。

独立版本管理 。每个 Kit 有自己的 API 版本。@kit.CryptoArchitectureKit 的某个 API 被废弃了,不影响 @kit.ArkUI 的任何功能。开发者可以针对单个 Kit 做版本迁移,不需要"一次性升级所有 API"。

缩小攻击面。应用只加载它真正使用的 Kit。一个不需要网络请求的应用根本不会加载网络相关的 Kit。从安全角度看,这减少了潜在的攻击入口。

HarmonyKit 依赖的四个核心 Kit

@kit.ArkUI:UI 框架、路由与窗口管理

@kit.ArkUI 是 ArkUI 声明式 UI 框架的基础 Kit。它提供了 UI 组件(Text、Button、Column、Grid 等)、页面路由(router)、窗口管理(window)等最核心的能力。

在 HarmonyKit 中,@kit.ArkUI 的使用分为两部分:

第一部分是无需显式 import 的全局能力------这些是 ArkUI 框架级别的基础设施,在每个 .ets 文件中自动可用:

typescript 复制代码
// 这些装饰器和组件是全局可用的,不 import
@Entry
@Component
struct Index {
  @State currentIndex: number = 0;

  build() {
    Column() {
      Text('HarmonyKit')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
      // Grid, ForEach, Scroll, Button 等都是全局组件
    }
    .backgroundColor('#f5f5f5')
  }
}

@Entry@Component@State 这些装饰器,以及 TextButtonColumnRowGrid 等基础组件都是 ArkUI 框架的全局命名空间------不需要 import。它们是 ArkUI 的"语言级别"的能力。

第二部分是需要显式 import 的工具类和 API ------这些需要通过 @kit.ArkTS@kit.ArkUI 导入:

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

// util.TextEncoder 用于将字符串编码为 Uint8Array
let encoder = new util.TextEncoder('utf-8');
let uint8Array: Uint8Array = encoder.encodeInto(input);

// util.Base64Helper 用于 Base64 编解码
let helper = new util.Base64Helper();
return helper.encodeToStringSync(uint8Array);

// util.TextDecoder 用于将 Uint8Array 解码为字符串
let decoder = util.TextDecoder.create('utf-8');
return decoder.decodeToString(uint8Array);

@kit.ArkTS 是 ArkTS 语言运行时 Kit,提供了 util 命名空间,包含 TextEncoderTextDecoderBase64Helperbuffer 等工具类。这些能力在 Web 标准中有对应 API(TextEncoder/TextDecoder 是 WHATWG Encoding 标准),但 HarmonyKit 使用的是鸿蒙的实现。

注意 @kit.ArkTS@kit.ArkUI 的区别:ArkTS 是语言运行时 Kit(提供底层工具类),ArkUI 是 UI 框架 Kit(提供组件和路由)。两个 Kit 定位不同但同属鸿蒙基础能力层。

EntryAbility.ets 中可以看到 @kit.ArkUI 的窗口管理能力:

typescript 复制代码
import { window } from '@kit.ArkUI';

onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.loadContent('pages/Index', (err) => {
    if (err.code) {
      hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
      return;
    }
    hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
  });
}

window.WindowStage 管理应用的主窗口生命周期。loadContent() 方法是 ArkUI 框架级别的"应用入口",它将一个 ArkUI 页面加载到窗口中,启动 UI 渲染。

@kit.UIDesignKit:HDS 设计系统

@kit.UIDesignKit 提供了 HDS(Harmony Design System)组件和沉浸光感材质系统。在 HarmonyKit 中,它是一个"用了但只在关键位置使用"的 Kit------仅用于主页的底部导航。

typescript 复制代码
import { hdsMaterial, HdsTabs, HdsTabsController } from '@kit.UIDesignKit';

HdsTabs({ controller: this.controller }) {
  ForEach(CATEGORIES, (cat: string) => {
    TabContent() {
      this.ToolGrid(cat)
    }
    .tabBar(cat)
  })
}
.barOverlap(true)
.barFloatingStyle({
  barBottomMargin: 36,
  adaptToHandedness: true,
  systemMaterialEffect: {
    materialType: hdsMaterial.MaterialType.ADAPTIVE,
    materialLevel: hdsMaterial.MaterialLevel.ADAPTIVE
  }
})

一行 import 引入了三个命名空间:

  • HdsTabs:HDS 版本标签页组件
  • HdsTabsController:标签页状态控制器
  • hdsMaterial:材质配置命名空间,包含 MaterialType 和 MaterialLevel 枚举

@kit.UIDesignKit 的定位是"设计系统的代码实现"。它不提供新的底层能力(模糊、圆角、阴影这些在 ArkUI 基础层都有),但它将这些能力封装为符合 HDS 设计规范的高级组件------开发者不需要手动调参毛玻璃半径、胶囊圆角路径、色相偏移量,只需要声明"我要用 HDS 标准底部导航",框架负责实现全部的视觉效果。

@kit.CryptoArchitectureKit:加密与哈希计算

@kit.CryptoArchitectureKit 提供了加密算法框架。在 HarmonyKit 中,它用于哈希计算工具页的 MD5/SHA1/SHA256 计算:

typescript 复制代码
import { cryptoFramework } from '@kit.CryptoArchitectureKit';

let md = cryptoFramework.createMd(algorithm);
let uint8Array = new Uint8Array(buffer.from(input, 'utf-8').buffer);
await md.update({ data: uint8Array });
let result = await md.digest();
return buffer.from(result.data).toString('hex');

cryptoFramework.createMd() 创建一个消息摘要(Message Digest)实例。传入的 algorithm 参数是字符串字面量 'MD5''SHA1''SHA256'createMd() 是同步方法,但 md.update()md.digest() 是异步的------因为哈希计算可能涉及硬件加速(如芯片内置的加密引擎),需要通过异步接口等待硬件操作完成。

这个 API 的设计很巧妙。它把"创建摘要实例"(同步)和"执行计算"(异步)分离开来。这样设计的好处是:在多线程场景下,可以先在主线程快速创建实例,然后在工作线程中异步执行 updatedigest,不阻塞 UI。

@kit.CryptoArchitectureKit 的命名中有"Architecture"一词,因为它是 HarmonyOS 安全架构的一部分。它不仅提供消息摘要(哈希),还提供对称加密(AES/DES)、非对称加密(RSA/ECC)、密钥管理、数字签名等完整密码学能力。对 HarmonyKit 来说,只用了其中的哈希部分,但这个 Kit 的能力远不止于此。

@kit.BasicServicesKit:系统基础服务

@kit.BasicServicesKit 提供了系统底层服务,包括剪贴板、电量和屏幕等。HarmonyKit 使用了剪贴板服务来实现"复制到剪贴板"功能:

typescript 复制代码
import { pasteboard } from '@kit.BasicServicesKit';

// 在 CopyButton 组件中
.onClick(() => {
  if (this.text.length > 0) {
    let data = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, this.text);
    let sysPasteboard = pasteboard.getSystemPasteboard();
    sysPasteboard.setData(data, (err) => {
      if (err) {
        this.getUIContext().getPromptAction().showToast({ message: '复制失败', duration: 1500 });
      } else {
        this.getUIContext().getPromptAction().showToast({ message: '已复制到剪贴板', duration: 1500 });
      }
    });
  }
})

剪贴板 API 的调用分为三步:

  1. pasteboard.createData() 创建一个剪贴板数据对象,指定 MIME 类型和内容
  2. pasteboard.getSystemPasteboard() 获取系统剪贴板实例
  3. sysPasteboard.setData() 将数据写入系统剪贴板,回调函数处理成功/失败

注意 setData 是异步的(通过回调),因为剪贴板操作需要进程间通信(IPC)------系统剪贴板服务运行在独立进程中。MIMETYPE_TEXT_PLAIN 常量表示文本类型。@kit.BasicServicesKit 还支持 MIMETYPE_TEXT_HTML(富文本)和 MIMETYPE_TEXT_URI(URI 链接)等类型,但 HarmonyKit 只需要纯文本。

其他相关 Kit 简介

除了核心依赖的四个 Kit,HarmonyKit 项目还使用了两个辅助 Kit:

@kit.PerformanceAnalysisKit:日志系统

typescript 复制代码
import { hilog } from '@kit.PerformanceAnalysisKit';

const DOMAIN = 0x0000;

hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));

hilog 是鸿蒙的日志系统,类似于 Android 的 LogcatDOMAIN 是日志域(一个十六进制数,应用自定义),testTag 是日志标签,%{public}s 是格式化字符串(%{public} 前缀表示此参数是"公开的",可以被日志系统完整输出;如果是 %{private},日志系统会隐藏参数内容以保护隐私)。

@kit.AbilityKit:应用生命周期

typescript 复制代码
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    try {
      this.context.getApplicationContext().setColorMode(
        ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
      );
    } catch (err) {
      hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
    }
  }

  onDestroy(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onForeground(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

UIAbility 是鸿蒙应用的 UI 能力单元------每个有 UI 的鸿蒙应用都必须有一个继承自 UIAbility 的类。onCreateonDestroyonForegroundonBackground 等生命周期回调和 Android 的 Activity 生命周期非常相似。注意 COLOR_MODE_NOT_SET 的用法------它关闭了应用级别的颜色模式覆盖,让应用跟随系统的深色/浅色模式设置。这是 HarmonyKit 的选择:不强制浅色或深色,跟随用户系统偏好。

Want 类型是鸿蒙的"意图"------类似于 Android 的 Intent,用于描述应用启动的触发条件(比如用户点击桌面图标、其他应用通过 URL scheme 拉起等)。

为什么 HarmonyKit 零第三方依赖

HarmonyKit 的 oh-package.json5 中,dependencies 字段是空的:

json5 复制代码
{
  "modelVersion": "6.1.1",
  "description": "Please describe the basic information.",
  "dependencies": {},
  "devDependencies": {
    "@ohos/hypium": "1.0.25",
    "@ohos/hamock": "1.0.0"
  }
}

只有两个 devDependencies------hypium(鸿蒙官方测试框架)和 hamock(鸿蒙官方 mock 框架)------它们只在开发和测试阶段使用,不出现在生产构建中。

没有第三方依赖的原因不是"刻意追求零依赖",而是自然形成的结果:

第一,系统 Kit 覆盖了全部需求。 加密哈希有 @kit.CryptoArchitectureKit,Base64 编解码有 @kit.ArkTSutil.Base64Helper,剪贴板有 @kit.BasicServicesKit------所有这些在 Android 开发中需要引入第三方库的能力,在鸿蒙上系统直接提供且 API 设计一致。

第二,纯计算类工具不需要网络、不读文件、不用 Canvas。 HarmonyKit 的 10 个工具全部基于"输入字符串 -> 输出字符串"的模型。这个模型不需要网络请求库(如 OkHttp/Retrofit),不需要图片加载库(如 Glide/Coil),不需要持久化存储(如 Room/Realm)。输入和输出的全部计算都在设备本地完成,系统 Kit 完全够用。

第三,鸿蒙第三方生态尚在发展期。 客观地说,鸿蒙平台的第三方 npm 包数量和质量还在增长中。这倒逼开发者更充分地挖掘系统 Kit 的能力------结果证明系统 Kit 的能力比预期的更全面。

Kit 的版本管理与 API 迁移

每个 Kit 有独立的 API 生命周期。有些 API 会被标记为"已废弃"(deprecated),编译器会在使用废弃 API 时发出警告,但代码仍然可以编译和运行。HarmonyKit 中遇到的一个例子是路由 API 的演进:

typescript 复制代码
// 旧写法(全局 router,编译器可能警告)
import { router } from '@kit.ArkUI';
router.pushUrl({ url: 'pages/tools/JsonFormatter' });

// 新写法(通过 UI 上下文获取 router,推荐)
this.getUIContext().getRouter().pushUrl({ url: this.tool.routerPath });

router.pushUrl() 是全局路由器 API,在多窗口场景下可能路由到错误的窗口(如果有多个窗口同时存在)。this.getUIContext().getRouter() 获取的是当前 UI 上下文绑定的路由器实例,确保路由目标始终与当前窗口对应。这是 API 演进的典型模式------旧 API 依然可用,但新 API 更安全、更精确。编译器不会强制开发者迁移(旧代码依然可以编译通过),但会通过 warning 提示"有更好的写法"。

Kit 级别的版本管理让这种渐进式迁移成为可能。@kit.ArkUI 的路由 API 更新了,不影响 @kit.CryptoArchitectureKit 的任何接口。开发者可以逐个 Kit 地进行 API 升级,而不是一口气迁移整个应用的 API。

Kit 的模块化与包体积

从包体积角度看,Kit 的模块化也是有利的。第三方库往往是"全量引入"------你用了库的一个 Base64 方法,但 node_modules 里拉下来的是整个库的全部代码。Kit 的模块化意味着系统可以按需加载------@kit.CryptoArchitectureKit 的哈希计算代码在首次调用 cryptoFramework.createMd() 时才加载到内存,而不是应用启动时就全部驻留。

在 HarmonyKit 的应用包中,10 个工具页的全部代码量约 1000 行 ArkTS,加上组件和 model 约 300 行,总共约 1300 行业务代码。没有第三方库的代码包含在 APK 中。app 包体积完全由业务代码 + 鸿蒙基础运行时 + 系统 Kit 的引用元数据组成。对于"开发者工具箱"这种应用来说,小巧的包体积本身就是竞争力的体现。

总结

Kit 模块化体系是 HarmonyOS 区别于 Android/iOS 的一个根本性架构特征。它通过将系统能力按功能域拆分为独立、版本独立、懒加载的 Kit,为开发者提供了以下核心价值:

能力可见性:看 import 就知道文件依赖了哪些系统能力。代码审查、安全审计、权限声明------所有这些流程都因为 Kit 的显式导入而变得更加简单。

版本独立演进:每个 Kit 有独立的 API 生命周期。一个 Kit 的 API 废弃不影响其他 Kit。渐进式迁移成为可能。

零依赖成为可能:当系统 Kit 覆盖了足够多的能力时,"零第三方依赖"不再是一种"追求",而是一种自然结果。HarmonyKit 的经验证明:对于纯计算类的开发者工具应用,系统 Kit 足够强大。

按需加载与安全:应用只加载真正使用的 Kit,减少了冷启动时间和潜在攻击面。

对于 HarmonyKit 来说,四个核心 Kit 覆盖了 UI、设计系统、加密、系统服务四个领域------不需要一个第三方库。这不是"不使用第三方库"的教条主义,而是"系统 Kit 确实够好"的客观事实。如果你的鸿蒙应用也需要做到零依赖,首先评估系统 Kit 是否覆盖了你的需求------答案很可能是"覆盖了"。

项目仓库:https://atomgit.com/VON-/harmony-kit

相关推荐
Geek-Chow1 小时前
微服务认证与授权:06 — Keycloak / IdP
微服务·信息可视化·架构
在书中成长1 小时前
HarmonyOS 小游戏《对战五子棋》开发第9篇 - GomokuEngine核心引擎设计(四):悔棋功能与历史记录管理
华为·harmonyos
BreezeJiang1 小时前
为什么你调的 LLM 接口不值钱?——从零理解 Agent 开发的正确姿势
人工智能·架构
李燚2 小时前
五个适配器:DeepFlux 如何把 Eino 接进 DDD 架构
架构·ddd·eino·deepflux
我叫张小白。2 小时前
一个微服务电商+社区项目(瓷韵app)的技术深度复盘
docker·微服务·云原生·架构
_abab2 小时前
Java面试宝典:从基础到架构2
java·面试·架构
会周易的程序员3 小时前
microLog 的 log_reader 架构解析:嵌入式日志检索引擎的设计之道
c++·物联网·架构·日志·iot·aiot
Geek-Chow3 小时前
微服务认证与授权:08 — OPA(PDP)
微服务·云原生·架构
阿标在干嘛3 小时前
100+微服务的统一出入口:政策快报平台的API网关设计
微服务·云原生·架构