请添加图片描述

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

本文对应模块:Web 层的数据备份与恢复实现,包括本地备份导出、备份导入校验、与原生层的备份插件联动。

📌 概述

对于任务管理类应用来说,数据往往承载了用户的大量投入和长期使用成果,一旦丢失会带来非常大的挫败感。因此,可靠的数据备份与恢复能力是整个应用的重要安全保障。备份不仅要包含任务本身,还要覆盖分类、标签、提醒、习惯、目标等多个维度的数据,并且在恢复时能够正确地校验格式、避免损坏现有数据。

在 Web 层,我们通过 BackupManager 将不同来源的数据聚合成一个统一的备份对象,然后序列化为 JSON 文本供用户下载或交给原生层保存。导入时,再从 JSON 中解析出各类数据,按顺序写回本地数据库。为了避免恢复错误,我们在导入之前会检查版本号、必需字段等基本信息,如果发现结构不符合预期就立刻中止,避免污染现有数据。

在鸿蒙原生层,我们可以通过 Cordova 插件提供更接近系统的存储位置,例如应用缓存目录或用户可选的导出目录,从而让备份文件能够在系统级文件管理器中被看到和管理。Web 层通过 cordova.exec() 调用原生插件完成真正的文件读写,自己只需关心数据结构本身。这种分工可以让 Web 代码保持简洁,同时充分利用鸿蒙原生的存储和权限体系。

🔧 备份管理器实现

下面的 BackupManager 展示了一个简化后的导出与导入逻辑,专注于如何拼装备份数据和校验导入内容。

// 备份管理器的关键方法
class BackupManager {
  static exportData() {
    const data = {
      version: '1.0',
      exportDate: new Date().toISOString(),
      tasks: taskManager.getAllTasks(),
      categories: categoryManager.getAllCategories()
    };
    return JSON.stringify(data, null, 2);
  }

  static async importData(jsonData) {
    const data = JSON.parse(jsonData);
    if (!data.version || !Array.isArray(data.tasks)) {
      throw new Error('无效的备份文件格式');
    }

    await db.clearAllTasks();
    for (const task of data.tasks) {
      await db.addTask(task);
    }
    for (const category of data.categories || []) {
      await db.addCategory(category);
    }
    await taskManager.loadTasks();
    await categoryManager.loadCategories();
  }
}

代码解释:

BackupManager.exportData() 会从多个管理器中收集当前内存中的数据,包括任务列表和分类列表,并附带版本号和导出时间,最终使用 JSON.stringify 生成带缩进的字符串,方便人类阅读和调试。importData() 则负责从备份字符串恢复数据:首先用 JSON.parse 解析文本,然后检查 version 字段是否存在、tasks 是否为数组,如果不符合预期就抛出错误提示“无效的备份文件格式”。在确认格式正确后,先通过 db.clearAllTasks() 清空现有任务数据,再遍历 tasks 数组逐条写入数据库,同时按需导入 categories。最后调用 taskManager.loadTasks() 和 categoryManager.loadCategories() 重新加载内存中的数据,使 UI 能立即反映恢复后的结果。

🔌 原生层的备份插件

在鸿蒙原生侧,我们通过 ArkTS 插件来负责真正的文件保存和读取。这样可以把备份文件放在应用缓存目录或用户选定的目录中,并利用系统的文件访问能力。

// ArkTS 代码示例 - 数据备份插件
import { CordovaPlugin, CallbackContext } from '@magongshou/harmony-cordova/Index';
import { PluginResult, MessageStatus } from '@magongshou/harmony-cordova/Index';

export class BackupPlugin extends CordovaPlugin {
  // 保存备份文件
  async saveBackup(callbackContext: CallbackContext, args: string[]): Promise<void> {
    try {
      const backupJson = args[0];
      console.log('[BackupPlugin] 收到备份数据,长度:', backupJson.length);
      // 这里应写入应用缓存目录或用户选择的目录
      const result = PluginResult.createByString(MessageStatus.OK, '备份已保存');
      callbackContext.sendPluginResult(result);
    } catch (error) {
      const result = PluginResult.createByString(MessageStatus.ERROR, (error as Error).message);
      callbackContext.sendPluginResult(result);
    }
  }

  // 读取备份文件内容
  async loadBackup(callbackContext: CallbackContext, args: string[]): Promise<void> {
    try {
      // 这里应从磁盘读取备份文件内容
      const dummy = '{}';
      const result = PluginResult.createByString(MessageStatus.OK, dummy);
      callbackContext.sendPluginResult(result);
    } catch (error) {
      const result = PluginResult.createByString(MessageStatus.ERROR, (error as Error).message);
      callbackContext.sendPluginResult(result);
    }
  }
}

原生代码解释:

BackupPlugin 保存了两个核心方法:saveBackup 与 loadBackup。saveBackup 接收来自 Web 层的备份 JSON 字符串,打印日志以便调试,然后在实际项目中应该将数据写入应用缓存目录或用户选定的备份目录;完成后通过 PluginResult 返回“备份已保存”的 OK 状态。loadBackup 用于从磁盘读取之前保存的备份文件内容,并以字符串形式返回给 Web 层;一旦发生 I/O 或解析错误,会捕获异常并返回 ERROR 状态。通过这种分工,Web 层只负责数据结构定义,原生层负责具体文件路径和权限控制。

🌉 Web 层通知原生备份操作

下面的两个函数展示了 Web 层如何通过 Cordova 调用 BackupPlugin,在用户点击“导出”或“导入”时与原生层协同工作。

// JavaScript 代码 - 调用原生备份插件
async function exportBackupToNative() {
  const backupJson = BackupManager.exportData();
  cordova.exec(
    () => { console.log('原生层已保存备份文件'); },
    (error) => { console.error('备份保存失败:', error); },
    'BackupPlugin',
    'saveBackup',
    [backupJson]
  );
}

async function importBackupFromNative() {
  cordova.exec(
    async (backupJson) => {
      try {
        await BackupManager.importData(backupJson);
        console.log('备份已导入并应用到本地数据库');
      } catch (error) {
        console.error('导入失败:', error);
      }
    },
    (error) => { console.error('读取备份失败:', error); },
    'BackupPlugin',
    'loadBackup',
    []
  );
}

Web 层代码解释:

exportBackupToNative() 首先调用 BackupManager.exportData() 生成完整的备份 JSON 字符串,然后通过 cordova.exec() 调用 BackupPlugin.saveBackup,将备份内容作为参数传递给原生层。如果原生层保存成功,就在控制台打印“已保存备份文件”的日志,失败则打印错误详情。importBackupFromNative() 则调用 BackupPlugin.loadBackup 从原生层读取备份内容,在成功回调中使用 BackupManager.importData() 完成本地数据库的恢复,如果在解析或写入过程中出现问题,会在控制台给出详细的错误输出,便于定位异常。

📝 总结

数据备份与恢复是保护用户数据安全的重要一环。通过 BackupManager 统一导出与导入数据结构,可以保证备份文件结构清晰、易于校验;通过 BackupPlugin 将备份文件存放在鸿蒙原生可管理的目录中,则可以利用系统级文件管理能力,让用户更安全地保管和迁移数据。Web 层与原生层的协同让备份既简单可用,又足够可靠,为整个任务管理应用提供了最后一道“保险”。

Logo

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

更多推荐