【OpenHarmony/HarmonyOs 】从零打造数字生活入口:LinkOS 链界项目架构全解析
【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.pushUrl 与 router.replaceUrl:进入网页详情时使用 push,用户能够返回;底部一级导航使用 replace,避免导航栈无限累积。这个细节会直接影响返回键体验。
八、当前架构的优点与可改进点
已有优点 ✅
- 页面、数据、业务和基础设施已经分层。
- 所有外部网址统一走 HTTPS 校验。
- Preferences 被封装为单例,避免页面重复初始化。
- 角色预置和网址模型为云同步预留了结构。
- UI 使用统一 Token,便于后续主题化。
后续改进 🚧
- 将散落在多个页面中的底部导航提取为公共组件。
- 将字符串和颜色进一步迁移到资源文件,完善深色模式与国际化。
- 自定义网址增多后,从 JSON + Preferences 迁移到关系型数据库或 Cloud DB。
- URL 安全检查接入真实安全服务,不依赖本地模拟黑名单。
- AI Key 只能保存在云函数侧,客户端绝不能硬编码密钥。
九、总结
一个导航应用看起来简单,但真正做好会涉及启动分流、状态持久化、搜索、防抖、URL 规范化、安全校验、Web 容器、跨应用跳转与多端适配。LinkOS 的价值并不只在 UI,而在于它提供了一套可逐步扩展的 HarmonyOS NEXT 应用骨架。
在后续文章中,我们会把每条链路单独展开,展示从 ArkTS 数据模型到 ArkUI 交互的完整实现。🚀

更多推荐

所有评论(0)