OpenHarmony 英语学习 App 实战:近场快传、跨端续学与全场景学习闭环 OpenHarmony 英语学习 App 实战近场快传、跨端续学与全场景学习闭环摘要英语学习天然是一个跨场景任务早上通勤路上用手机背几个单词晚上回家用平板继续做语法练习周末和同学互相分享学习成果。单设备 App 很容易形成“学习孤岛”而 OpenHarmony/HarmonyOS 的全场景能力正好可以把学习数据、学习状态和学习成果连接起来。➡️本文以我的英语学习项目「英语视界 YingYu」为例分享如何围绕学习场景设计近场快传、跨端续学、分布式数据同步以及实况窗扩展思路。项目中已经包含ShareKit分享监听、DistributedKVStore初始化、UIAbility onContinue()续接能力等代码基础非常适合写成一套全场景学习闭环。一、全场景学习体验应该解决什么问题在教育类应用里全场景并不是为了“炫技术”而是为了解决真实学习问题用户换设备后学习进度不要丢今日学习任务可以在系统级入口看到学习报告可以快速分享给同学或家长手机和平板之间能自然接续网络不稳定时基础学习数据仍然可用。因此「英语视界」的全场景设计围绕三个关键词展开分享用碰一碰/隔空传送快速分享学习报告同步用分布式数据能力同步轻量学习数据续接用 UIAbility 生命周期完成跨设备学习状态恢复。二、近场快传碰一碰分享学习报告项目中封装了ShareService.ts通过kit.ShareKit的harmonyShare监听近场分享事件。import{ systemShare, harmonyShare }fromkit.ShareKitimport{ uniformTypeDescriptorasutd }fromkit.ArkDataexportfunctionregisterKnockShare(callback: (target: harmonyShare.SharableTarget) void):void{try{ harmonyShare.on(knockShare,(target: harmonyShare.SharableTarget) {console.info(Triggered Knock Share)callback(target) }) }catch(err) {console.error(Register knock share failed:${JSON.stringify(err)}) } }除了碰一碰还注册了隔空传送能力exportfunctionregisterGesturesShare(callback: (target: harmonyShare.SharableTarget) void):void{try{ harmonyShare.on(gesturesShare,(target: harmonyShare.SharableTarget) {console.info(Triggered Gestures Share)callback(target) }) }catch(err) {console.error(Register gestures share failed:${JSON.stringify(err)}) } }对于学习 App 来说近场分享非常适合这些场景同学之间分享今日学习成果给家长展示连续打卡天数分享自定义生词本分享成就徽章分享待复习任务。三、生命周期中注册和注销分享监听在MainTabsV2.ets中页面出现时注册监听页面销毁时注销监听。aboutToAppear(): void {this.isTabletDevice isTablet()this.isPhone !this.isTabletDevice deviceInfo.deviceType phonethis.loadData()this.registerShareListeners() } aboutToDisappear(): void {this.unregisterShareListeners() }注册逻辑如下registerShareListeners():void{if(this.isPhone) { registerKnockShare((target: harmonyShare.SharableTarget){ handleShareFromKnock(target,learning_record) }) registerGesturesShare((target: harmonyShare.SharableTarget){ handleShareFromKnock(target,learning_record) }) } }注销逻辑unregisterShareListeners():void{if(this.isPhone) {unregisterKnockShare()unregisterGesturesShare()} }这里有两个设计点只在手机设备上启用近场分享页面离开时及时注销监听避免资源长期占用。这种写法更符合移动端能力使用习惯也便于后续扩展到不同设备。四、学习报告内容不要直接分享冷冰冰的 JSON分享内容不是技术数据而是给用户看的学习成果。项目中定义了LearningRecordShareDataexportinterfaceLearningRecordShareData {totalWords:numbertotalDays:numberconsecutiveDays:numberachievementsCount:numberachievementsTotal:numbercustomWordsCount:numberreviewDueCount:numbertodayProgress:stringshareDate:string}然后把这些数据格式化成自然语言exportfunctiongenerateLearningRecordText(data:LearningRecordShareData):string{return 我的英语学习报告\n\n ${data.shareDate}\n\n✨ 已学单词: ${data.totalWords} 个\n 学习天数: ${data.totalDays} 天\n 连续打卡: ${data.consecutiveDays} 天\n 获得成就: ${data.achievementsCount}/${data.achievementsTotal}\n 自定义词: ${data.customWordsCount} 个\n 待复习: ${data.reviewDueCount} 个\n\n 坚持学习遇见更好的自己\n 使用「趣味英语」App 一起学习吧~}这样的分享文案比 JSON 更适合传播因为它具备可读性成就感鼓励感社交表达价值。五、真正发起分享SharedData target.share当系统触发近场分享后项目会生成文本内容并包装成SharedData。exportasyncfunctionhandleShareFromKnock(target: harmonyShare.SharableTarget,type: ShareContentType learning_record):Promiseboolean {try{constshareText generateShareText(type)constshareData: systemShare.SharedDatanewsystemShare.SharedData({utd: utd.UniformDataType.TEXT,content: shareText }) target.share(shareData)console.info(Knock/Gestures share initiated successfully)returntrue}catch(err) {console.error(Knock share failed:${JSON.stringify(err)})returnfalse} }这里使用TEXT类型是因为学习报告天然适合复制、转发和保存。后续也可以继续扩展分享学习海报图片分享 AppLink分享某个单词本分享复习计划分享班级排行榜。六、分布式 KV让学习数据跟着设备走除了分享学习 App 更重要的是“连续性”。项目里通过DistributedSync.ets初始化分布式 KV。import{ distributedKVStore }fromkit.ArkDataconstSTORE_IDyingyu_distributed_storeletkvStore: distributedKVStore.SingleKVStore|nullnullexportasyncfunctioninitDistributedStore(context: Context):Promisevoid {constkvManagerConfig: distributedKVStore.KVManagerConfig {bundleName:ying.yu.app,context: context }constkvManager distributedKVStore.createKVManager(kvManagerConfig) }存储选项如下const options:distributedKVStore.Options{createIfMissing:true,encrypt:false,backup:false,autoSync:true,kvStoreType:distributedKVStore.KVStoreType.SINGLE_VERSION,securityLevel:distributedKVStore.SecurityLevel.S1}kvStoreawaitkvManager.getKVStoredistributedKVStore.SingleKVStore(STORE_ID,options)这里最重要的是autoSync: true数据变更后支持自动同步SINGLE_VERSION适合轻量键值数据SecurityLevel.S1用于基础学习数据backup: false避免不必要的数据备份。适合同步的数据包括已学单词 ID每日学习目标连续打卡天数成就解锁状态用户年级设置今日复习进度。不建议同步的数据包括大段听力音频临时 UI 状态敏感身份信息可重新计算的缓存数据。七、跨设备续接手机学完平板继续项目还在EntryAbility.ets中实现了onContinue()用于跨设备迁移学习状态。onContinue(wantParam: Recordstring,Object): AbilityConstant.OnContinueResult {try{constsettings AppStorage.getstring(yingyu_settings) ||constprogress AppStorage.getstring(yingyu_progress) ||constlearnedWords AppStorage.getstring(yingyu_learned_words) ||wantParam[yingyu_settings] settings wantParam[yingyu_progress] progress wantParam[yingyu_learned_words] learnedWords wantParam[yingyu_timestamp] Date.now().toString()returnAbilityConstant.OnContinueResult.AGREE }catch(err) {returnAbilityConstant.OnContinueResult.MISMATCH } }这个函数做的事情非常明确把跨设备续接所需的最小数据写入wantParam。目标设备启动后通过onCreateWithWant()恢复onCreateWithWant(want: Want,launchParam: AbilityConstant.LaunchParam): void { this.onCreate(want,launchParam)if(want.parameters) { const settings want.parameters[yingyu_settings]asstringconst progress want.parameters[yingyu_progress]asstringconst learnedWords want.parameters[yingyu_learned_words]asstringif(settings)AppStorage.setOrCreate(yingyu_settings,settings)if(progress)AppStorage.setOrCreate(yingyu_progress,progress)if(learnedWords)AppStorage.setOrCreate(yingyu_learned_words,learnedWords)} }这样就能实现手机上打开词汇学习切换到平板平板恢复学习设置和已学进度用户继续学习不需要重新选择。八、全场景体验的产品价值如果只从技术上看近场分享、分布式 KV、跨端续接是三个独立能力。但放到英语学习场景里它们会形成闭环用户在手机上完成今日单词学习进度同步到分布式数据回家后用平板继续练听力学完后碰一碰分享学习报告家长或同学收到报告用户获得反馈和激励。这就是“全场景”真正有价值的地方它把学习行为从单点操作变成连续体验。九、实况窗扩展思路当前项目还没有完整接入实况窗但学习场景非常适合做实况窗扩展。可以考虑展示今日任务完成度8/10 个单词待复习数量还有 5 个单词听力播放状态正在播放第 3 条材料复习倒计时下次复习还有 20 分钟打卡提醒今日还未完成目标。建议后续抽象一个统一状态模型interfaceLearningLiveState {taskTitle:stringcurrent:numbertotal:numberstatus:learning|reviewing|listening|completedupdatedAt:number}然后从DailyTask、ReviewCenter、ListeningContent等页面收集状态再对接系统级展示。这样实况窗不会变成孤立功能而是学习流程的自然延伸。十、实现时需要注意的点1. 分享监听要跟生命周期绑定不要在全局长期注册监听。页面出现时注册离开时注销逻辑更清楚也更节省资源。2. 分享内容要可读学习报告面向用户不是面向程序。优先分享自然语言文本再考虑 JSON 或结构化数据。3. 同步数据要轻量分布式 KV 适合轻量状态不适合大文件。同步学习进度、设置、成就更合适。4. 续接数据要最小化跨设备续接只带必要字段避免把无关数据一起迁移。5. 实况窗要服务任务实况窗不应该只是“展示存在感”而应该帮助用户快速知道当前学习任务的状态。十一、小结本文结合「英语视界 YingYu」项目梳理了 OpenHarmony/HarmonyOS 全场景能力在英语学习 App 中的落地方式使用ShareKit实现碰一碰和隔空传送将学习数据转成可读文本报告使用SharedData发起近场分享使用分布式 KV 存储轻量学习状态使用onContinue()和onCreateWithWant()完成跨设备续接基于学习任务扩展实况窗能力。全场景不是简单地“多设备支持”而是让用户在不同设备、不同时间、不同场景下都能接着学。对于教育类 App 来说这种连续性就是体验优势。