在这里插入图片描述

引言

当你第一次打开一个 HarmonyOS 工程时,面对几十个 .ets 文件和一堆 json5 配置,往往会感到无从下手。本篇的目标是帮你建立"全局地图":先搞清楚 ContinuePublish 这个项目是什么、演示了什么能力、用到了哪些技术、代码是怎么分模块组织的,然后再逐篇深入细节。

读完本篇,你将收获:

  • 理解"基于自由流转实现社交通讯协同"这一项目主题的含义;
  • 认识本项目演示的六大核心场景;
  • 了解项目用到的关键技术栈(Stage 模型、ArkTS、ArkUI、分布式能力);
  • 看懂工程的顶层模块划分与代码组织方式;
  • 为后续七篇文章搭建整体框架。

一、项目是什么

本项目演示的技术底座有四块:

  1. 应用接续(App Continuation):应用在一台设备上运行到一半,可以把状态"搬"到另一台设备继续运行;
  2. 分布式数据对象(Distributed Data Object):跨设备同步一份内存数据,多端读写实时一致;
  3. 分布式文件系统(Distributed File System):跨设备访问、传输文件资源(图片、视频);
  4. 跨设备互通与分享服务:拖拽、剪贴板、系统分享面板、碰一碰/隔空传送等系统级能力。

这些能力组合在一起,就构成了一个真实的场景:用户在手机上编辑一条带图片、文字、位置的内容,随手就能在平板、电脑上继续编辑、浏览、分享——这正是"自由流转"的形态。

二、六大核心场景

README 的效果图预览(screenshots/device/ 目录下的截图)与应用功能,可以归纳为六大场景:

场景 说明 对应截图
1. 内容发布 编辑标题、正文、图片/视频、位置信息 publishPage.png
2. 跨设备媒体互通 通过系统能力调用远端设备的相机、图库、文档扫描,把图片/视频回传到本端 fromOther.png
3. 跨设备拖拽 开启键鼠共享后,将本端图片/文字直接拖到对端设备 onDrop.png
4. 跨设备剪贴板 图片/视频/文字复制到系统剪贴板,在对端粘贴(数据在跨设备剪贴板中保留 2 分钟) copy.png
5. 系统分享 浏览详情页通过系统分享面板分享给同账号设备,直达对应页面 systemShare.png
6. 碰一碰/隔空传送 通过碰一碰或隔空传送手势,把页面分享给附近设备 knockShare.pnggesturesShare.png

此外,场景 9 提到的应用接续贯穿始终:在本端打开"内容发布"应用后,对端设备 Dock 栏会出现接续图标,点击即可把当前编辑状态(标题、正文、图片列表等)整体迁移到对端继续编辑。这是本项目区别于普通示例的最大亮点——它不是单一功能演示,而是把分布式能力串成了一个完整应用。

三、关键技术栈

根据 build-profile.json5(根目录)与 hvigor/hvigor-config.json5,项目的基础信息非常明确:

  • HarmonyOS SDK:6.1.0(API 23),targetSdkVersioncompatibleSdkVersion 均为 6.1.0(23)
  • 开发框架:Stage 模型(apiType: "stageMode");
  • 开发语言:ArkTS(ArkTS 是 TypeScript 的超集,在 ArkUI 声明式 UI 中使用);
  • UI 范式:ArkUI 声明式开发(@Entry/@Component 装饰的结构体即页面);
  • 运行设备:手机(phone)、平板(tablet)、电脑(2in1),见 entry/src/main/module.json5deviceTypes

需要说明的是,HarmonyOS 6.1.0 中 Kit 化接口是主流导入方式。本项目的 entry/src/main/ets/entryability/EntryAbility.ets 开头就集中展示了这种导入风格:

import {
  AbilityConstant,
  UIAbility,
  Want,
  EnvironmentCallback,
  ConfigurationConstant,
  wantConstant
} from '@kit.AbilityKit';
import { commonType, distributedDataObject } from '@kit.ArkData';
import { KeyboardAvoidMode, window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { JSON } from '@kit.ArkTS';
import { i18n } from '@kit.LocalizationKit';
  • @kit.AbilityKit:UIAbility 生命周期、Want 意图、环境回调等应用框架能力;
  • @kit.ArkData:分布式数据对象(distributedDataObject)——本项目跨设备传数据的主力;
  • @kit.ArkUI:窗口(window)与键盘避让模式;
  • @kit.PerformanceAnalysisKithilog 日志组件,项目中所有日志都通过它输出;
  • @kit.LocalizationKiti18n 国际化能力,用于读取系统偏好语言。

这种"按 Kit 分组导入"的写法是 HarmonyOS 新版本工程的典型风格,也是初学者最容易困惑的地方——看到 @kit.xxx 不必慌张,它只是把相关 API 归类的导入路径。

4. 四个容易混淆的概念

对初学者来说,以下四个词经常被混为一谈,这里先做一次澄清(后续文章会逐一展开):

  • Stage 模型:应用框架层面的开发模型,定义了应用的组成方式(Ability、窗口、上下文)。与之相对的是老旧的 FA 模型;
  • ArkTS语言,HarmonyOS 应用代码的书写语言,是 TypeScript 的超集;
  • ArkUIUI 框架,负责界面声明与渲染,采用声明式范式,配套状态管理、组件、布局等体系;
  • Kit能力包,把系统能力(Ability、分布式数据、窗口、日志……)按领域打包,通过 @kit.xxx 导入使用。

一句话串联:用 ArkTS 语言,基于 Stage 模型组织应用结构,借助 ArkUI 声明式地描述界面,通过 Kit 调用系统能力——这就是本项目乃至所有 HarmonyOS 应用的开发套路。

5. 项目规模速览

在深入代码前,先对项目规模有个体感(数字来自工程真实目录):

  • 代码区 entry/src/main/ets/ 下约 30 个 .ets 文件,分布在 constants(3 个)、entryability(1 个)、model(7 个)、pages(1 个)、utils(6 个)、view(11 个)、viewmodel(2 个)七个目录;
  • 资源区 entry/src/main/resources/ 下有 base、zh_CN、en_US、rawfile 四类资源目录,瀑布流示例图片 8 张、mock 数据 JSON 2 个;
  • 截图与动图素材 20 余个,位于 screenshots/device/
  • 全工程零三方依赖oh-package.json5dependencies 为空),所有能力都来自系统 Kit。

这个规模对新手非常友好:没有历史包袱、没有外部依赖,可以逐文件通读。

四、工程模块划分

项目的顶层目录结构如下(可在工程根目录看到):

ContinuePublish/
├── AppScope/                  // 应用级配置与资源
│   ├── app.json5              // 应用唯一标识、版本号、图标、名称
│   └── resources/             // 应用级资源(app_icon 等)
├── entry/                     // 唯一的模块(HAP 模块)
│   ├── build-profile.json5    // 模块级构建配置(含混淆规则)
│   ├── hvigorfile.ts          // 模块级构建脚本
│   ├── oh-package.json5       // 模块级依赖清单
│   ├── obfuscation-rules.txt  // 混淆规则文件
│   └── src/main/
│       ├── module.json5       // 模块配置文件(核心!)
│       ├── ets/               // ArkTS 代码区
│       └── resources/         // 模块资源区
├── hvigor/                    // 构建工具版本配置
├── screenshots/               // 效果图与演示动图
├── build-profile.json5        // 工程级构建配置
├── hvigorfile.ts              // 工程级构建脚本
└── oh-package.json5           // 工程级依赖清单

对初学者来说,最需要记住的一句话是:AppScope 管"应用",entry 管"模块",hvigor 管"构建"。本项目只有一个 entry 模块(类型为 entry,即应用入口模块),module.json5 中声明的 mainElementEntryAbility,即应用启动时首先加载的 UIAbility。

代码区 entry/src/main/ets/ 的组织方式(与 README「工程目录」一节一致):

  • constants/:常量类,包括 CommonConstants.ets(公共常量)、HomeConstants.ets(浏览列表常量)、BreakpointConstants.ets(响应式断点常量);
  • entryability/:UIAbility 入口类 EntryAbility.ets,应用的生命周期与接续逻辑都在这里;
  • model/:数据实体类,如 ContentInfo.ets(发布内容)、WaterFlowData.ets(瀑布流数据);
  • pages/:页面目录,目前只有 Index.ets,是应用的"首页"(Navigation 容器);
  • utils/:工具类,如 WantUtil.ets(Want 解析)、FileUtil.ets(文件复制)、BreakpointSystem.ets(断点计算);
  • view/:视图组件目录,按功能拆分为 contentBrowse(内容浏览)与 contentEditor(内容编辑)两个子模块;
  • viewmodel/:视图状态与数据处理,如 FooterTabData.ets(底部页签数据)、WaterFlowListData.ets(瀑布流数据处理)。

这种"constants / model / pages / utils / view / viewmodel"的划分,是官方示例比较推荐的工程结构:视图与数据分离、模块按业务拆分,值得初学者模仿。

五、从入口看整体架构

理解了目录,我们再从"入口"串一遍应用是怎么跑起来的,这比背目录更有用。

1. 应用从哪里启动

module.json5mainElement 指向 EntryAbility,系统启动应用时创建该 UIAbility 实例。EntryAbility.etsonCreate 中完成初始化(读取语言、设置颜色模式、处理接续/分享参数),在 onWindowStageCreate 中调用 windowStage.loadContent('pages/Index', ...) 加载首页 Index.ets

2. 首页如何组织

Index.ets 是一个 @Entry @Component 修饰的结构体,使用 Navigation(this.pageInfos) 作为根容器,页面上两个按钮分别跳转到"内容编辑"(ContentEditorPage)与"内容浏览"(ContentBrowsePage):

Navigation(this.pageInfos) {
  Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween }) {
    Text($r('app.string.title'))
      .fontSize(30)
      .fontWeight(FontWeight.Bold)

    Column({ space: 12 }) {
      Button($r('app.string.button1'))
        .width('100%')
        .onClick(async () => {
          // 点击后跳转到内容编辑页(路由名来自 route_map.json)
          this.pageInfos.pushPathByName('ContentEditorPage', null, true);
        })

      Button($r('app.string.button2'))
        .width('100%')
        .onClick(async () => {
          // 点击后跳转到内容浏览页
          this.pageInfos.pushPathByName('ContentBrowsePage', null, true);
        })
    }
  }
}

注意这里 pageInfosNavPathStack 类型,通过 @StorageLink('pageInfos') 与 AppStorage 全局状态绑定——所有页面共享同一个导航栈。页面跳转的目标(ContentEditorPageContentBrowsePageContentDetailSamplePage)并不在 main_pages.json 中声明,而是通过 entry/src/main/resources/base/profile/route_map.jsonrouterMap 以命名路由方式注册。这种"命名路由 + NavPathStack"的方式是本项目页面导航的核心机制。

3. 分布式能力在哪里汇聚

项目的灵魂在 EntryAbility.ets 的两个方法:

  • onContinue(wantParam):本端发起接续时被系统回调,把当前编辑状态(标题、正文、媒体列表、位置信息)打包成分布式数据对象并保存;
  • restoreDistributedObject(want, launchParam):对端接收到接续时,恢复数据并写入 AppStorage,供页面读取。

用一个比喻理解:onContinue 是"打包行李",restoreDistributedObject 是"拆包入住"。两个方法配合 module.json5 中的 "continuable": true 声明,就构成了完整的应用接续能力。详细机制将在第 6 篇《Stage 模型与 UIAbility 生命周期》展开。

4. 数据模型如何贯穿

跨设备传输的核心数据模型是 ContentInfo(位于 entry/src/main/ets/model/ContentInfo.ets),它把一条"待发布内容"抽象为七个字段:标题、正文、媒体列表、是否显示位置、是否添加位置、选中位置、附件资源。无论是本端编辑、还是跨设备接续,数据都以它为载体,这体现了**“模型先行”**的设计思路。

六、分布式能力全景

本项目之所以被称为"自由流转"示例,是因为它把三大分布式能力组装成了一个完整的协同体验。这里先从"能力"角度梳理一遍,后续各篇会结合代码逐个深入。

1. 应用接续:状态跟着人走

接续(Continuation)是本项目的核心场景。技术要点:

  • 配置侧:module.json5"continuable": true + "launchType": "singleton"
  • 代码侧:EntryAbility.onContinue() 在本端打包数据,对端通过 restoreDistributedObject() 恢复;
  • 数据载体:ContentInfo 模型 + 分布式数据对象 + 分布式文件系统附件。

2. 分布式数据对象:内存级跨设备同步

distributedDataObject(来自 @kit.ArkData)是本项目跨设备传数据的主力:两端通过同一个 sessionId 关联数据对象,任一端的属性修改都会自动同步到另一端。它的特点是使用起来像操作本地对象——不需要自己写网络传输。

3. 分布式文件系统:文件随数据流转

媒体文件(图片/视频)不直接塞进数据对象,而是通过 commonType.Asset 描述、借助分布式文件系统传输,对端用 fileCopy 复制到本地沙箱(见 utils/FileUtil.ets)。这样大文件传输可以走文件通道,不阻塞数据同步。

4. 系统级分享通道

拖拽(跨设备拖拽)、剪贴板(跨设备复制粘贴)、系统分享面板、碰一碰/隔空传送——这些看起来是"功能",本质都是系统提供的跨设备通道,应用只需在正确的时机调用正确的入口即可。

把这四条串起来的完整业务流是:

手机编辑内容(标题/正文/图片/位置)
   │ 应用接续
   ▼
电脑继续编辑(数据经分布式数据对象同步,媒体经分布式文件系统传输)
   │ 拖拽/剪贴板
   ▼
平板协同(补充图片、文字)
   │ 系统分享 / 碰一碰 / 隔空传送
   ▼
附近设备直达详情页(App Linking 链接直达)

七、运行与验证环境速览

在深入代码之前,先记住运行本项目的硬性条件(详见 README.md「约束与限制」):

  • 支持设备:手机、平板、电脑(仅标准系统);
  • 系统版本:HarmonyOS 6.1.0 Release 及以上;开发工具 DevEco Studio 6.1.0 Release 及以上;
  • 双端必须登录同一华为账号,且都打开 Wi-Fi 与蓝牙开关(接入同一局域网可提升传输速度);
  • 应用接续要求双端都安装本应用(同 UIAbility 之间触发);
  • 跨设备拖拽需打开键鼠共享(且必须包含一台电脑);
  • 隔空传送分享需打开设备侧隔空传送开关。

这些约束的本质是:自由流转依赖"同一账号 + 系统分布式框架",账号是设备间的信任基础,Wi-Fi/蓝牙是设备发现与数据传输的通道。

八、小结

本篇我们从"是什么"讲到"怎么组织",建立了 ContinuePublish 的全局认知:

  1. 项目主题:基于自由流转实现社交通讯协同,核心是"内容发布 + 内容浏览"场景下的多设备无缝协作;
  2. 六大场景:内容发布、跨设备媒体互通、拖拽、剪贴板、系统分享、碰一碰/隔空传送,外加贯穿全程的应用接续;
  3. 技术栈:HarmonyOS 6.1.0(API 23)、Stage 模型、ArkTS、ArkUI 声明式范式、分布式数据对象;
  4. 工程组织:AppScope(应用级)与 entry(模块级)双层结构,代码按 constants/entryability/model/pages/utils/view/viewmodel 分层;
  5. 运行链路:EntryAbility.onCreate → onWindowStageCreate → loadContent('pages/Index') → Navigation 导航
  6. 接续链路:onContinue 打包 → restoreDistributedObject 恢复,数据载体是 ContentInfo 与分布式数据对象。

接下来的七篇文章将逐个击破:场景演示与运行环境(02)、工程目录(03)、配置文件(04)、构建体系(05)、Stage 模型与生命周期(06)、ArkTS 语言(07)、ArkUI 范式(08)。我们下篇见。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐