数据备份恢复Cordova与OpenHarmony混合开发实战
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
📌 概述
数据备份恢复模块允许用户创建和恢复应用数据的备份。在Cordova与OpenHarmony混合开发框架下,这个模块提供了完整的备份和恢复功能,用户可以定期备份数据,并在需要时恢复数据。数据备份恢复功能的设计目标是为用户提供数据安全保障,防止数据丢失。
数据备份恢复模块采用了自动备份和手动备份的设计,用户可以根据需要选择备份方式。
🔗 完整流程
第一步:备份创建
当用户点击备份按钮时,系统首先从IndexedDB数据库中收集所有数据。系统会将数据转换为JSON格式,然后创建一个备份文件,并保存到本地存储或文件系统中。
备份过程包括数据收集、格式转换、文件创建等步骤。系统会记录备份的时间和大小,以便用户查看备份历史。
第二步:备份管理
系统会显示所有现有的备份文件,用户可以查看备份的时间、大小等信息。用户可以选择删除不需要的备份,或者下载备份文件。
第三步:数据恢复
当用户点击恢复按钮时,系统会从选定的备份文件中读取数据,然后将数据导入到IndexedDB数据库中。恢复过程包括文件读取、数据解析、验证、导入等步骤。
🔧 Web代码实现
HTML结构
数据备份恢复页面的HTML结构包含三个主要部分:备份操作、备份历史和恢复操作。备份操作部分包含创建备份和自动备份开关按钮。备份历史部分显示所有已创建的备份文件列表。恢复操作部分允许用户选择备份文件并恢复数据。
<div id="backup-page" class="page">
<div class="page-header">
<h1 class="page-title">数据备份恢复</h1>
</div>
<div class="page-content">
<!-- 备份操作 -->
<div class="section">
<h2>备份操作</h2>
<div class="form-actions">
<button class="btn btn-primary" onclick="backupModule.createBackup()">
创建备份
</button>
<button class="btn btn-default" onclick="backupModule.autoBackupToggle()">
<span id="auto-backup-status">启用自动备份</span>
</button>
</div>
</div>
<!-- 备份列表 -->
<div class="section">
<h2>备份历史</h2>
<div id="backup-list" class="backup-list">
<!-- 动态生成的备份项目 -->
</div>
</div>
<!-- 恢复操作 -->
<div class="section">
<h2>恢复数据</h2>
<div class="form-group">
<label for="restore-file" class="form-label">选择备份文件</label>
<input
type="file"
id="restore-file"
class="form-input"
accept=".json"
/>
</div>
<div class="form-actions">
<button class="btn btn-primary" onclick="backupModule.restoreBackup()">
恢复数据
</button>
</div>
</div>
</div>
</div>
JavaScript逻辑
数据备份恢复模块的核心是BackupModule类。在初始化时,模块会从本地存储加载现有的备份列表,并检查自动备份是否启用。备份数据包括所有Bug和分类信息,以JSON格式存储。
class BackupModule {
constructor() {
this.backups = [];
this.autoBackupEnabled = false;
this.init();
}
async init() {
await this.loadBackups();
this.loadAutoBackupStatus();
}
async loadBackups() {
try {
const backupList = JSON.parse(localStorage.getItem('backup_list') || '[]');
this.backups = backupList;
this.renderBackups();
} catch (error) {
console.error('加载备份列表失败:', error);
}
}
}
loadBackups方法首先从本地存储获取备份列表,然后调用renderBackups方法将备份列表渲染到页面上。renderBackups方法遍历所有备份,为每个备份生成一个HTML元素,显示备份的名称、大小和时间,以及下载和删除按钮。
renderBackups() {
const html = this.backups.map((backup, index) => `
<div class="backup-item">
<div class="backup-info">
<span class="backup-name">备份 ${index + 1}</span>
<span class="backup-size">${(backup.size / 1024).toFixed(2)} KB</span>
</div>
<div class="backup-date">${utils.formatDate(backup.timestamp)}</div>
<div class="backup-actions">
<button class="action-btn" onclick="backupModule.downloadBackup(${index})">下载</button>
<button class="action-btn" onclick="backupModule.deleteBackup(${index})">删除</button>
</div>
</div>
`).join('');
document.getElementById('backup-list').innerHTML = html || '<p>暂无备份</p>';
}
createBackup方法负责创建新的备份。它首先从数据库收集所有Bug和分类数据,然后将这些数据转换为JSON格式。备份信息(包括时间戳和大小)被保存到备份列表中,而备份内容被保存为单独的localStorage项。
async createBackup() {
try {
utils.showLoading('正在创建备份...');
const bugs = await db.getAllBugs();
const categories = await db.getAllCategories();
const backupData = {
timestamp: new Date().toISOString(),
bugs: bugs,
categories: categories
};
const backupContent = JSON.stringify(backupData);
const backup = {
timestamp: new Date().toISOString(),
size: backupContent.length,
content: backupContent
};
this.backups.unshift(backup);
localStorage.setItem('backup_list', JSON.stringify(this.backups.map(b => ({
timestamp: b.timestamp,
size: b.size
}))));
localStorage.setItem(`backup_${backup.timestamp}`, backupContent);
utils.hideLoading();
utils.showSuccess('备份创建成功');
this.renderBackups();
} catch (error) {
console.error('创建备份失败:', error);
utils.hideLoading();
utils.showError('创建备份失败');
}
}
restoreBackup方法处理数据恢复。用户选择一个备份文件后,系统会读取文件内容并解析JSON数据。在恢复前,系统会要求用户确认,因为恢复操作会覆盖现有数据。确认后,系统会清空现有数据并导入备份中的所有数据。
async restoreBackup() {
const fileInput = document.getElementById('restore-file');
const file = fileInput.files[0];
if (!file) {
utils.showError('请选择备份文件');
return;
}
try {
const content = await this.readFile(file);
const backupData = JSON.parse(content);
if (confirm('确定要恢复这个备份吗?现有数据将被覆盖。')) {
utils.showLoading('正在恢复数据...');
await db.clearAll();
for (let bug of backupData.bugs) {
await db.addBug(bug);
}
for (let category of backupData.categories) {
await db.addCategory(category);
}
utils.hideLoading();
utils.showSuccess('数据恢复成功');
fileInput.value = '';
}
} catch (error) {
console.error('恢复备份失败:', error);
utils.hideLoading();
utils.showError('恢复备份失败');
}
}
readFile方法使用FileReader API读取用户选择的文件内容。这个方法返回一个Promise,在文件读取成功时resolve,失败时reject。downloadBackup方法允许用户下载已创建的备份文件,通过创建一个Blob对象并模拟点击下载链接来实现。
readFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target.result);
reader.onerror = (e) => reject(e);
reader.readAsText(file);
});
}
downloadBackup(index) {
const backup = this.backups[index];
const content = localStorage.getItem(`backup_${backup.timestamp}`);
const blob = new Blob([content], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `backup_${backup.timestamp}.json`;
a.click();
URL.revokeObjectURL(url);
}
deleteBackup方法允许用户删除不需要的备份。系统会要求用户确认删除操作。确认后,备份文件会从localStorage中删除,备份列表也会更新。loadAutoBackupStatus和autoBackupToggle方法用于管理自动备份功能的启用和禁用状态。
deleteBackup(index) {
if (confirm('确定要删除这个备份吗?')) {
const backup = this.backups[index];
localStorage.removeItem(`backup_${backup.timestamp}`);
this.backups.splice(index, 1);
localStorage.setItem('backup_list', JSON.stringify(this.backups.map(b => ({
timestamp: b.timestamp,
size: b.size
}))));
this.renderBackups();
utils.showSuccess('备份已删除');
}
}
loadAutoBackupStatus() {
this.autoBackupEnabled = JSON.parse(localStorage.getItem('auto_backup_enabled') || 'false');
this.updateAutoBackupButton();
}
autoBackupToggle() {
this.autoBackupEnabled = !this.autoBackupEnabled;
localStorage.setItem('auto_backup_enabled', JSON.stringify(this.autoBackupEnabled));
this.updateAutoBackupButton();
utils.showSuccess(this.autoBackupEnabled ? '自动备份已启用' : '自动备份已禁用');
}
updateAutoBackupButton() {
const btn = document.getElementById('auto-backup-status');
btn.textContent = this.autoBackupEnabled ? '禁用自动备份' : '启用自动备份';
}
}
const backupModule = new BackupModule();
CSS样式
备份列表的样式使用Flexbox布局,使备份项目能够垂直排列。每个备份项目包含备份信息和操作按钮。备份项目在鼠标悬停时会改变背景颜色,提高用户体验。
.backup-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.backup-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: white;
border-radius: 4px;
border: 1px solid #ddd;
}
.backup-info {
display: flex;
align-items: center;
gap: 15px;
}
.backup-name {
font-weight: 500;
color: #333;
}
.backup-size {
color: #999;
font-size: 12px;
}
.backup-date {
color: #999;
font-size: 12px;
}
.backup-actions {
display: flex;
gap: 8px;
}
🔌 OpenHarmony原生代码
OpenHarmony原生代码通过BackupPlugin类实现备份相关的原生功能。createBackup方法负责在原生文件系统中创建备份文件。首先获取应用的缓存目录,然后创建备份目录(如果不存在),最后将备份数据写入JSON文件。
import { hilog } from '@kit.PerformanceAnalysisKit';
import { fileIo } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
const TAG: string = '[BackupPlugin]';
const DOMAIN: number = 0xFF00;
export class BackupPlugin {
static async createBackup(success: Function, error: Function, args: any[]): Promise<void> {
try {
const context = getContext(this) as common.UIAbilityContext;
const backupData = args[0];
const backupDir = context.cacheDir + '/backups';
const backupFile = backupDir + `/backup_${Date.now()}.json`;
if (!fileIo.accessSync(backupDir)) {
fileIo.mkdirSync(backupDir);
}
const file = fileIo.openSync(backupFile, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE);
fileIo.writeSync(file.fd, JSON.stringify(backupData));
fileIo.closeSync(file.fd);
hilog.info(DOMAIN, TAG, `备份创建成功: ${backupFile}`);
success(backupFile);
} catch (err) {
hilog.error(DOMAIN, TAG, `创建备份失败: ${err}`);
error('创建备份失败');
}
}
}
Web-Native通信
Web层通过BackupBridge类与原生代码进行通信。createBackup方法使用Cordova的exec方法调用原生的BackupPlugin,将备份数据传递给原生代码。原生代码在文件系统中创建备份文件后,将文件路径返回给Web层。这个通信过程是异步的,使用Promise来处理成功和失败的回调。
class BackupBridge {
static createBackup(backupData) {
return new Promise((resolve, reject) => {
if (window.cordova) {
cordova.exec(
(filePath) => {
console.log('备份创建成功:', filePath);
resolve(filePath);
},
(error) => {
console.error('创建备份失败:', error);
reject(error);
},
'BackupPlugin',
'createBackup',
[backupData]
);
} else {
reject('Cordova未加载');
}
});
}
}
📝 总结
数据备份恢复模块是BugTracker Pro应用中用于数据安全保护的重要功能。在Cordova与OpenHarmony混合开发框架下,它提供了完整的备份和恢复功能。通过定期备份数据,用户可以有效防止数据丢失,这大大提高了应用的可靠性。
模块采用了模块化的设计,各个功能都是独立的,易于维护和扩展。这充分展示了混合开发框架的优势。
更多推荐


所有评论(0)