【OpenHarmony/HarmonyOs 】BackupExtensionAbility 入门:应用备份与恢复能力如何设计

发布时间:2026/7/23 2:37:54
【OpenHarmony/HarmonyOs 】BackupExtensionAbility 入门:应用备份与恢复能力如何设计 【OpenHarmony/HarmonyOs 】BackupExtensionAbility 入门应用备份与恢复能力如何设计前言用户重新安装或更换设备后身份偏好、收藏和快捷入口是否能够恢复是数据体验的重要部分。LinkOS 已经注册BackupExtensionAbility并允许备份恢复但当前回调只记录日志属于能力骨架。本文介绍它如何工作以及怎样把骨架完善成可靠实现。一、注册备份扩展在module.json5中声明{name:EntryBackupAbility,srcEntry:./ets/entrybackupability/EntryBackupAbility.ets,type:backup,exported:false,metadata: [ {name:ohos.extension.backup,resource:$profile:backup_config} ] }它不是用户直接打开的页面而是系统备份框架在合适场景调用的扩展能力。exported: false避免普通外部应用直接启动。二、允许备份恢复backup_config.json当前内容为{allowToBackupRestore:true}该开关只表示允许进入备份恢复流程不意味着业务数据已经自动得到正确迁移。开发者仍需明确哪些文件或数据属于备份范围并验证恢复后的兼容性。三、当前 Ability 骨架exportdefaultclassEntryBackupAbilityextendsBackupExtensionAbility{asynconBackup() { hilog.info(DOMAIN,Backup,onBackup ok);awaitPromise.resolve(); }asynconRestore(bundleVersion: BundleVersion) { hilog.info(DOMAIN,Backup,onRestore version: %{public}s,JSON.stringify(bundleVersion) );awaitPromise.resolve(); } }它能证明回调链存在但没有导出、迁移或校验数据。文章或产品说明中不能把它描述成“已完成数据备份”。系统回调与业务备份逻辑也不应该全部写在 Ability 类里。更合适的职责划分是EntryBackupAbility └─ 接收系统回调、记录结果、控制超时 ↓BackupService└─ 创建快照、校验、迁移、恢复 ↓ Repository └─ 读取或写入Preferences、RDB、文件这样备份规则可以独立单元测试未来从 Preferences 迁移 RDB 时也不必重写系统入口。四、哪些数据值得备份LinkOS 本地数据可以分级数据建议自定义网址备份价值最高快捷入口 ID备份但恢复后需过滤身份与兴趣备份恢复个性化体验语言和视图模式可备份也可跟随系统访问统计视产品隐私策略决定搜索联想缓存不备份可重新获取AI 临时回复默认不备份除非提供会话功能API Key/Token不以普通文件方式备份备份遵循最小化能重新生成的缓存不备份敏感凭据使用专门安全机制。五、数据快照要带版本不要只把当前 JSON 原样复制。建议定义快照interfaceBackupSnapshot{schemaVersion:number;createdAt:number;roleId:string;interests:string[];customSites:UrlItem[];quickEntryIds:string[];locale:string;viewMode:string;}schemaVersion用于数据结构升级createdAt用于排查快照新旧。它与应用版本不是一回事应用版本可多次变化而备份数据格式可能保持不变。还可以为快照增加完整性元数据interfaceBackupEnvelope{format:string;// 固定为 linkos-backupschemaVersion:number;createdAt:number;payload:BackupPayload;checksum?:string;}format防止把其他 JSON 误当备份checksum 可用于发现传输或存储损坏但它不是防篡改签名。若威胁模型包含恶意修改需要使用由安全密钥保护的消息认证机制。六、如何创建一致的数据快照备份过程中用户可能继续修改收藏。如果先读取角色、过几秒再读取网址快照可能来自不同时间点。数据量较小时可以暂时串行读取并阻止写入迁移到 RDB 后应使用只读事务获得一致视图。伪代码如下classBackupService{asynccreateSnapshot(): PromiseBackupSnapshot{constroleId awaitthis.storage.get(StorageKeys.USER_ROLE_ID,)asstring;constinterestsJson awaitthis.storage.get(StorageKeys.USER_INTERESTS,[])asstring;constsitesJson awaitthis.storage.get(StorageKeys.CUSTOM_SITES,[])asstring;constquickJson awaitthis.storage.get(StorageKeys.QUICK_ENTRY_URL_IDS,[])asstring;return{ schemaVersion:1, createdAt: Date.now(), roleId, interests:this.safeStringArray(interestsJson), customSites:this.safeSites(sitesJson), quickEntryIds:this.safeStringArray(quickJson).slice(0,5), locale:awaitthis.readLocale(), viewMode:awaitthis.readViewMode() }; } }这里仍然复用安全解析函数不能因为数据来自本应用就放弃校验。磁盘数据本身可能已经损坏。七、恢复时必须校验恢复数据来自旧版本不能直接覆盖。建议流程读取快照 → 校验文件结构和大小 → 检查 schemaVersion → 执行逐版本迁移 → 验证URL、ID、类型和上限 → 写入临时位置 → 全部成功后原子替换正式数据例如快捷入口可能指向已不存在的网址恢复后要与customSites presetSites取交集HTTP 地址应按新安全策略拒绝或升级重复 URL 应合并。推荐的字段校验roleId必须存在于当前 RoleFactory否则回退自定义或欢迎页interests只保留允许的标签并去重customSites要求 ID、标题和 HTTPS URL 合法相同 URL 只保留一条优先更新时间较新的记录quickEntryIds最多 5 个且必须引用有效站点locale只允许当前支持的语言viewMode只允许grid/list时间戳必须是有限非负数异常值回退。八、原子恢复与失败回滚最危险的做法是边解析边覆盖正式数据角色写成功、收藏写到一半失败应用就进入不一致状态。恢复应该先在内存完成验证和迁移再一次性提交。Preferences 没有复杂数据库事务时可以采用临时命名空间1.将全部恢复结果写入 linkos_restore_temp2.重新读取并校验临时数据3.设置 restore_ready 标记 4. 将临时数据切换为正式数据 5. 清理临时区和标记使用 RDB 后则应把写入放在事务中任何一步失败就 rollback。应用下次启动还应检查未完成恢复标记并执行清理或继续恢复。九、利用 BundleVersion 做迁移判断onRestore(bundleVersion)提供来源版本信息可用于日志和迁移分支。但更可靠的是快照内部 schemaVersion因为构建版本与数据协议不总是一一对应。switch(snapshot.schemaVersion) {case1: snapshot migrateV1ToV2(snapshot);case2:break;default:thrownewError(UNSUPPORTED_BACKUP_VERSION); }迁移应可重复测试并避免就地破坏原快照。多级迁移最好每次只负责相邻版本v1--migrateV1ToV2--v2--migrateV2ToV3--v3不要写一个充满条件分支的migrateAnyToLatest()。相邻迁移更容易单独测试也能复现任意历史版本升级链。例如 v2 新增categoryId时可把缺失值补为customv3 将分钟统计改成毫秒时迁移函数负责乘以 60000并记录已经完成避免重复换算。十、本地备份与云同步的关系有 Cloud DB 后仍可能需要系统备份云同步保存用户账号数据系统备份可保存设备偏好与游客数据。恢复时要定义优先级未登录用户恢复本地快照已登录用户先恢复设备偏好再同步云端收藏同一网址冲突按云版本和本地更新时间合并删除记录尊重云端墓碑避免恢复后复活。可以进一步定义合并优先级场景推荐策略本地有、云端无上传为新记录两端 URL 相同合并为一条保留较新标题云端已删除默认尊重删除墓碑本地游客数据登录后迁移先展示合并预览快捷入口冲突以当前设备偏好为主并限制 5 个系统备份面向设备恢复Cloud DB 面向账号同步两者目的不同。把它们简单理解为两个“谁覆盖谁”的数据源会带来丢失风险。十一、备份体积与性能备份回调不适合执行图片压缩、网络下载或长时间计算。图标、壁纸等大文件应根据平台备份机制和云存储策略单独处理。快照中尽量只保存资源引用与业务数据。性能原则包括限制单条标题、URL 和数组数量流式处理大文件避免一次全部加载内存缓存不进入备份记录条数、耗时和错误码不记录正文回调失败时返回明确状态不能只打印“ok”。十二、隐私与安全不备份访问令牌和 AI Key敏感字段加密不能只依赖硬编码密钥日志只记录数量、版本和错误码提供清除数据能力后旧备份是否还能恢复要符合平台和隐私政策对快照设置合理大小上限防止异常文件耗尽资源。如果备份包含访问统计或 AI 会话应在隐私说明中明确用途。用户执行“清除所有数据”后是否还能从系统备份自动恢复也要符合产品承诺和平台规则避免用户认为已经删除的数据重新出现。十三、可测试的 BackupService通过依赖注入让服务使用内存 RepositoryinterfaceBackupRepository {readSnapshotSource():PromiseBackupPayload;replaceAll(payload:BackupPayload):Promisevoid; }classBackupService{constructor(privaterepository: BackupRepository) {} }测试无需等待系统真正触发备份就能构造 v1、v2、损坏和超大快照。系统级测试只验证 Ability 能否正确调用 Service并在真机验证平台交付流程。十四、测试清单 ✅空数据备份与恢复正常收藏和设置恢复损坏 JSON、缺字段和超大文件旧 schema 逐级迁移重复网址与非法 HTTP 地址快捷入口引用失效恢复中断后原数据不被破坏云端数据与本地快照冲突release 签名包在真机执行。还应测试两次恢复同一快照是否得到相同结果即“幂等性”。若每恢复一次就产生新 ID 或重复网址用户多次迁移设备后数据会不断膨胀。十五、总结BackupExtensionAbility 只是系统调用入口真正的备份能力来自数据清单、版本化快照、恢复校验、原子写入和冲突策略。LinkOS 当前已经完成注册和回调骨架下一步应先保护最有价值的自定义网址再逐步加入偏好、快捷入口与旧版本迁移。☁️