【OpenHarmony/HarmonyOs 】从零打造数字生活入口:LinkOS 链界项目架构全解析

📌 本文以一个真实的 HarmonyOS NEXT 项目为例,介绍如何使用 ArkTS、ArkUI 与 Stage 模型构建集网址导航、个性化推荐、元服务入口和 AI 助手于一体的应用。

一、为什么要做“数字生活入口”

手机中的服务越来越多:开发者会频繁访问 GitHub 和 MDN,设计师需要 Figma 与 Behance,学生关注课程与资料,普通用户还会使用购物、出行、音乐等服务。传统浏览器书签只负责保存链接,却很少理解用户是谁、当前处于什么场景。

LinkOS 链界希望把这些入口重新组织起来:首次启动时选择身份,系统自动给出一组高质量站点;用户可以继续收藏自己的站点,也可以搜索、筛选并在应用内打开网页。进一步还可以通过 Want 拉起鸿蒙元服务,通过云函数接入 AI 和云同步。✨

二、项目当前能力

  • 👤 身份引导:开发者、设计师、学生、医生、摄影师等 11 种预置角色。
  • 🧭 导航首页:推荐站点、自定义收藏、关键词搜索、兴趣推荐和快捷入口。
  • 🔐 安全访问:网络层强制 HTTPS,打开链接前执行安全检查。
  • 🌐 Web 容器:使用 ArkWeb 加载网页,显示标题与加载进度。
  • ⚡ 元服务聚合:支持根据 bundleName、abilityName、moduleName 或 URI 构造 Want。
  • 🤖 AI 助手界面:具备消息模型、快捷提问和对话气泡,真实模型接口留作云函数接入。
  • 📊 使用统计:在 Ability 生命周期中累计前台使用时长与站点访问次数。

需要特别说明:AGC Cloud DB、Auth 和真实 DeepSeek 服务属于后续演进方向,当前仓库中的 AI 回复仍是本地模拟。技术文章应明确区分“已实现”与“计划接入”,这是对读者负责。

三、Stage 模型下的工程结构

项目采用一个 entry 模块,核心目录如下:

entry/src/main/
├── ets/
│   ├── entryability/       # UIAbility 生命周期与启动入口
│   ├── model/              # UrlItem、RolePreset 等领域模型
│   ├── service/            # 自定义网址业务服务
│   ├── utils/              # 存储、网络、安全、UI Token
│   └── pages/v2/           # 欢迎页、首页、元服务、AI、我的、WebView
└── resources/
    ├── base/               # 字符串、颜色、媒体资源
    ├── dark/               # 深色资源
    └── rawfile/web/        # 本地 Web 静态资源

这种划分把职责分成了四层:页面只负责状态和交互,Service 负责业务规则,Model 约束数据形状,Util 封装平台能力。对中小型 ArkTS 项目而言,它比把所有代码堆进一个页面更容易维护。

四、应用和模块配置

应用包名定义在 AppScope/app.json5,模块能力定义在 entry/src/main/module.json5。因为应用需要请求搜索建议并加载网页,所以必须声明网络权限:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "mainElement": "EntryAbility",
    "deviceTypes": ["phone", "tablet", "2in1"],
    "requestPermissions": [
      { "name": "ohos.permission.INTERNET" }
    ],
    "pages": "$profile:main_pages"
  }
}

页面路由还需要登记到 main_pages.json。没有登记的页面即使源码存在,也无法被正常加载:

{
  "src": [
    "pages/v2/WelcomePage",
    "pages/v2/HomePage",
    "pages/v2/MiniAppPage",
    "pages/v2/AIAssistantPage",
    "pages/v2/MinePage",
    "pages/v2/WebViewPage"
  ]
}

五、启动链路:Ability 决定首屏

UIAbility 是应用与系统生命周期连接的地方。窗口创建后,项目先初始化 Preferences,再判断用户是否已经选择身份,最后决定加载欢迎页还是首页:

async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
  const storage = StorageUtil.getInstance();
  await storage.init(this.context);

  const hasRole = await storage.has(StorageKeys.USER_ROLE_ID);
  const entryPage = hasRole
    ? 'pages/v2/HomePage'
    : 'pages/v2/WelcomePage';

  windowStage.loadContent(entryPage, (err) => {
    if (err.code) {
      hilog.error(DOMAIN, 'LinkOS', 'load failed: %{public}s', JSON.stringify(err));
    }
  });
}

这个实现体现了一个很实用的原则:启动决策应尽量集中在 Ability 层。页面不需要先显示再跳转,能减少闪屏,也避免多个页面重复判断首次启动状态。

六、领域数据如何设计

网址不是一个简单字符串,它还要支持分类、排序、同步和更新时间,因此定义为稳定的数据模型:

export interface UrlItem {
  id: string;
  title: string;
  url: string;
  icon?: string;
  categoryId: string;
  sort: number;
  createdAt: number;
  updatedAt: number;
}

createdAt 可用于审计,updatedAt 可用于最近编辑排序,也能为未来 Cloud DB 冲突合并提供依据。categoryId 使用 ID 而不是中文名称,可以避免国际化后数据失效。

七、页面之间如何协作

整个应用的主要链路可以概括为:

EntryAbility
   ├─ 未选择身份 → WelcomePage → 保存 roleId → HomePage
   └─ 已选择身份 → HomePage
                         ├─ 搜索/推荐 → SecurityUtil → WebViewPage
                         ├─ 自定义网址 → EntryManageService → Preferences
                         └─ 底部导航 → 元服务 / AI 助手 / 我的

页面跳转采用 router.pushUrlrouter.replaceUrl:进入网页详情时使用 push,用户能够返回;底部一级导航使用 replace,避免导航栈无限累积。这个细节会直接影响返回键体验。

八、当前架构的优点与可改进点

已有优点 ✅

  1. 页面、数据、业务和基础设施已经分层。
  2. 所有外部网址统一走 HTTPS 校验。
  3. Preferences 被封装为单例,避免页面重复初始化。
  4. 角色预置和网址模型为云同步预留了结构。
  5. UI 使用统一 Token,便于后续主题化。

后续改进 🚧

  1. 将散落在多个页面中的底部导航提取为公共组件。
  2. 将字符串和颜色进一步迁移到资源文件,完善深色模式与国际化。
  3. 自定义网址增多后,从 JSON + Preferences 迁移到关系型数据库或 Cloud DB。
  4. URL 安全检查接入真实安全服务,不依赖本地模拟黑名单。
  5. AI Key 只能保存在云函数侧,客户端绝不能硬编码密钥。

九、总结

一个导航应用看起来简单,但真正做好会涉及启动分流、状态持久化、搜索、防抖、URL 规范化、安全校验、Web 容器、跨应用跳转与多端适配。LinkOS 的价值并不只在 UI,而在于它提供了一套可逐步扩展的 HarmonyOS NEXT 应用骨架。

在后续文章中,我们会把每条链路单独展开,展示从 ArkTS 数据模型到 ArkUI 交互的完整实现。🚀

img

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐