HarmonyOS_ArkTs_API(3)
该系统基于鸿蒙HarmonyOS ArkTS构建,采用分层架构实现数据管理。核心包含内存缓存、本地存储和云端同步三层,使用鸿蒙原生API如dataPreferences、relationalStore等实现。本地存储分为轻量首选项(PreferenceManager)和关系型数据库(DatabaseManager)两类,前者处理配置信息,后者管理结构化数据。系统提供完整的CRUD操作和错误处理,确
·
HarmonyOS_ArkTs_API(3)
概述
数据持久化系统是此应用的基础架构组件,负责管理用户数据的存储、检索和同步。该系统基于鸿蒙HarmonyOS ArkTS构建,采用多层数据存储策略,确保用户梦想、任务和进度等关键信息可靠存储并随时可访问。系统集成了本地数据持久化与云端同步功能,在提供离线使用能力的同时,也保障了跨设备数据一致性。
技术架构
存储层级
数据持久化系统采用分层架构,包括以下几个核心层级:
- 内存缓存层:提供高速数据访问,减少IO操作
- 本地存储层:包含轻量级偏好设置和结构化数据存储
- 云端同步层:实现数据备份和多设备同步
核心技术选型
系统使用多种鸿蒙原生技术实现数据持久化:
// 相关技术导入
import dataPreferences from '@ohos.data.preferences';
import relationalStore from '@ohos.data.relationalStore';
import distributedKVStore from '@ohos.data.distributedKVStore';
import fileio from '@ohos.fileio';
本地数据存储实现
首选项存储
用于存储轻量级配置信息和用户偏好:
export class PreferenceManager {
private static instance: PreferenceManager;
private preferences: dataPreferences.Preferences = null;
private static PREFERENCE_NAME = 'dream_planner_prefs';
private constructor() {}
static getInstance(): PreferenceManager {
if (!PreferenceManager.instance) {
PreferenceManager.instance = new PreferenceManager();
}
return PreferenceManager.instance;
}
async init(context: Context): Promise<void> {
try {
this.preferences = await dataPreferences.getPreferences(context, PreferenceManager.PREFERENCE_NAME);
console.info('偏好设置初始化成功');
} catch (error) {
console.error(`偏好设置初始化失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async putString(key: string, value: string): Promise<void> {
try {
await this.preferences.put(key, value);
await this.preferences.flush();
} catch (error) {
console.error(`存储字符串失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async getString(key: string, defaultValue: string = ''): Promise<string> {
try {
return await this.preferences.get(key, defaultValue) as string;
} catch (error) {
console.error(`获取字符串失败: ${error instanceof Error ? error.message : String(error)}`);
return defaultValue;
}
}
async putNumber(key: string, value: number): Promise<void> {
try {
await this.preferences.put(key, value);
await this.preferences.flush();
} catch (error) {
console.error(`存储数值失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async getNumber(key: string, defaultValue: number = 0): Promise<number> {
try {
return await this.preferences.get(key, defaultValue) as number;
} catch (error) {
console.error(`获取数值失败: ${error instanceof Error ? error.message : String(error)}`);
return defaultValue;
}
}
async putBoolean(key: string, value: boolean): Promise<void> {
try {
await this.preferences.put(key, value);
await this.preferences.flush();
} catch (error) {
console.error(`存储布尔值失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async getBoolean(key: string, defaultValue: boolean = false): Promise<boolean> {
try {
return await this.preferences.get(key, defaultValue) as boolean;
} catch (error) {
console.error(`获取布尔值失败: ${error instanceof Error ? error.message : String(error)}`);
return defaultValue;
}
}
async removeKey(key: string): Promise<void> {
try {
await this.preferences.delete(key);
await this.preferences.flush();
} catch (error) {
console.error(`删除键值失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async clearAll(): Promise<void> {
try {
await this.preferences.clear();
await this.preferences.flush();
} catch (error) {
console.error(`清除所有偏好设置失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
}
// 使用示例
export async function saveUserToken(token: string): Promise<void> {
const prefManager = PreferenceManager.getInstance();
await prefManager.putString('user_token', token);
}
export async function getUserToken(): Promise<string> {
const prefManager = PreferenceManager.getInstance();
return await prefManager.getString('user_token', '');
}
关系型数据存储
用于存储结构化数据,如梦想和任务信息:
export class DatabaseManager {
private static instance: DatabaseManager;
private store: relationalStore.RdbStore = null;
private static DB_NAME = 'dream_planner.db';
private static DB_VERSION = 1;
// 数据库配置
private static getConfig(): relationalStore.StoreConfig {
return {
name: DatabaseManager.DB_NAME,
securityLevel: relationalStore.SecurityLevel.S1,
encrypt: false,
version: DatabaseManager.DB_VERSION
};
}
private constructor() {}
static getInstance(): DatabaseManager {
if (!DatabaseManager.instance) {
DatabaseManager.instance = new DatabaseManager();
}
return DatabaseManager.instance;
}
async init(context: Context): Promise<void> {
try {
this.store = await relationalStore.getRdbStore(context, DatabaseManager.getConfig());
await this.createTables();
console.info('数据库初始化成功');
} catch (error) {
console.error(`数据库初始化失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
private async createTables(): Promise<void> {
try {
// 创建梦想表
await this.store.executeSql(
`CREATE TABLE IF NOT EXISTS dreams (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
title TEXT NOT NULL,
description TEXT,
category INTEGER,
target_date TEXT,
progress INTEGER DEFAULT 0,
priority INTEGER DEFAULT 0,
status INTEGER DEFAULT 0,
cover_image TEXT,
created_at TEXT,
updated_at TEXT
);`
);
// 创建任务表
await this.store.executeSql(
`CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
dream_id INTEGER NOT NULL,
title TEXT NOT NULL,
description TEXT,
status INTEGER DEFAULT 0,
priority INTEGER DEFAULT 0,
deadline TEXT,
completion_date TEXT,
notes TEXT,
created_at TEXT,
updated_at TEXT,
FOREIGN KEY (dream_id) REFERENCES dreams (id) ON DELETE CASCADE
);`
);
// 创建进度记录表
await this.store.executeSql(
`CREATE TABLE IF NOT EXISTS progress_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
dream_id INTEGER NOT NULL,
task_id INTEGER,
progress_value INTEGER NOT NULL,
notes TEXT,
created_at TEXT,
FOREIGN KEY (dream_id) REFERENCES dreams (id) ON DELETE CASCADE,
FOREIGN KEY (task_id) REFERENCES tasks (id) ON DELETE SET NULL
);`
);
console.info('数据库表创建成功');
} catch (error) {
console.error(`创建数据库表失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async insert(table: string, values: relationalStore.ValuesBucket): Promise<number> {
try {
return await this.store.insert(table, values);
} catch (error) {
console.error(`插入数据失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async update(table: string, values: relationalStore.ValuesBucket, predicates: relationalStore.RdbPredicates): Promise<number> {
try {
return await this.store.update(values, predicates);
} catch (error) {
console.error(`更新数据失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async delete(predicates: relationalStore.RdbPredicates): Promise<number> {
try {
return await this.store.delete(predicates);
} catch (error) {
console.error(`删除数据失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async query(predicates: relationalStore.RdbPredicates): Promise<relationalStore.ResultSet> {
try {
return await this.store.query(predicates, null);
} catch (error) {
console.error(`查询数据失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
}
// 使用示例
export async function saveDreamLocally(dream: Dream): Promise<number> {
const dbManager = DatabaseManager.getInstance();
const values: relationalStore.ValuesBucket = {
user_id: dream.userId,
title: dream.title,
description: dream.description,
category: dream.category,
target_date: dream.targetDate,
priority: dream.priority,
status: dream.status,
progress: dream.progress,
cover_image: dream.coverImage,
created_at: getCurrentDateTime(),
updated_at: getCurrentDateTime()
};
return await dbManager.insert('dreams', values);
}
数据同步机制
云端同步策略
系统实现了智能同步策略,优化数据流量和电池使用:
export class DataSyncManager {
private static instance: DataSyncManager;
private syncTimer: number = -1;
private isSyncing: boolean = false;
private pendingChanges: Map<string, any[]> = new Map(); // 待同步的变更
private networkObserver: NetStatusListener = null;
private constructor() {
this.initNetworkObserver();
}
static getInstance(): DataSyncManager {
if (!DataSyncManager.instance) {
DataSyncManager.instance = new DataSyncManager();
}
return DataSyncManager.instance;
}
private initNetworkObserver(): void {
// 监听网络状态变化,适应同步策略
this.networkObserver = {
onNetStatusChange: (status: number) => {
if (status === 1) { // 网络可用
if (this.pendingChanges.size > 0) {
this.syncData(); // 网络恢复时立即尝试同步
}
}
}
};
// 注册网络观察者
network.subscribe(this.networkObserver);
}
// 开始定期同步
startPeriodicSync(intervalMinutes: number = 15): void {
if (this.syncTimer !== -1) {
return; // 已经在同步中
}
const intervalMs = intervalMinutes * 60 * 1000;
this.syncTimer = setInterval(() => {
this.syncData();
}, intervalMs);
console.info(`数据同步计划已启动,间隔${intervalMinutes}分钟`);
}
// 停止定期同步
stopPeriodicSync(): void {
if (this.syncTimer !== -1) {
clearInterval(this.syncTimer);
this.syncTimer = -1;
console.info('数据同步计划已停止');
}
}
// 添加待同步的变更
addChangeToSync(entityType: string, data: any): void {
if (!this.pendingChanges.has(entityType)) {
this.pendingChanges.set(entityType, []);
}
this.pendingChanges.get(entityType).push(data);
console.info(`已添加变更到同步队列: ${entityType}`);
}
// 执行数据同步
async syncData(): Promise<boolean> {
if (this.isSyncing) {
console.info('同步操作正在进行中,跳过本次同步');
return false;
}
// 检查网络连接
if (!await this.isNetworkAvailable()) {
console.info('网络不可用,同步操作将推迟');
return false;
}
try {
this.isSyncing = true;
console.info('开始数据同步...');
// 获取认证信息
const token = await getUserToken();
if (!token) {
console.info('用户未登录,同步操作取消');
return false;
}
// 处理每种实体类型的变更
for (const [entityType, changes] of this.pendingChanges.entries()) {
if (changes.length === 0) continue;
console.info(`同步实体类型: ${entityType}, 变更数量: ${changes.length}`);
// 调用API同步数据
const success = await this.syncEntityChanges(entityType, changes, token);
if (success) {
// 清除已同步的变更
this.pendingChanges.set(entityType, []);
}
}
// 下载服务器更新
await this.pullServerChanges(token);
console.info('数据同步完成');
return true;
} catch (error) {
console.error(`数据同步失败: ${error instanceof Error ? error.message : String(error)}`);
return false;
} finally {
this.isSyncing = false;
}
}
// 同步特定实体类型的变更
private async syncEntityChanges(entityType: string, changes: any[], token: string): Promise<boolean> {
try {
// 根据实体类型确定API端点
const endpoint = this.getEndpointByEntityType(entityType);
// 批量提交变更
const response = await request(
RequestMethod.POST,
endpoint,
changes,
{},
{ 'Authorization': `Bearer ${token}` }
);
console.info(`实体${entityType}同步成功, 响应: ${JSON.stringify(response)}`);
return true;
} catch (error) {
console.error(`同步${entityType}失败: ${error instanceof Error ? error.message : String(error)}`);
return false;
}
}
// 从服务器拉取变更
private async pullServerChanges(token: string): Promise<void> {
try {
// 获取最后同步时间戳
const prefManager = PreferenceManager.getInstance();
const lastSyncTime = await prefManager.getString('last_sync_time', '1970-01-01T00:00:00Z');
// 拉取服务器变更
const response = await request(
RequestMethod.GET,
'/sync/changes',
{ lastSyncTime },
{},
{ 'Authorization': `Bearer ${token}` }
);
// 处理服务器变更
if (response && response.changes) {
await this.processServerChanges(response.changes);
}
// 更新最后同步时间
await prefManager.putString('last_sync_time', getCurrentDateTime());
} catch (error) {
console.error(`拉取服务器变更失败: ${error instanceof Error ? error.message : String(error)}`);
}
}
// 处理服务器返回的变更
private async processServerChanges(changes: ServerChangeData): Promise<void> {
const dbManager = DatabaseManager.getInstance();
// 处理梦想更新
if (changes.dreams && changes.dreams.length > 0) {
for (const dream of changes.dreams) {
const predicates = new relationalStore.RdbPredicates('dreams');
predicates.equalTo('id', dream.id);
const result = await dbManager.query(predicates);
if (result.rowCount > 0) {
// 更新已存在的梦想
const values: relationalStore.ValuesBucket = {
title: dream.title,
description: dream.description,
category: dream.category,
target_date: dream.targetDate,
priority: dream.priority,
status: dream.status,
progress: dream.progress,
cover_image: dream.coverImage,
updated_at: getCurrentDateTime()
};
await dbManager.update('dreams', values, predicates);
} else {
// 插入新梦想
const values: relationalStore.ValuesBucket = {
id: dream.id,
user_id: dream.userId,
title: dream.title,
description: dream.description,
category: dream.category,
target_date: dream.targetDate,
priority: dream.priority,
status: dream.status,
progress: dream.progress,
cover_image: dream.coverImage,
created_at: dream.createdAt,
updated_at: getCurrentDateTime()
};
await dbManager.insert('dreams', values);
}
result.close();
}
}
// 处理任务更新 (类似梦想处理逻辑)
if (changes.tasks && changes.tasks.length > 0) {
// 任务更新处理逻辑...
}
}
// 根据实体类型获取API端点
private getEndpointByEntityType(entityType: string): string {
switch (entityType) {
case 'dream':
return '/sync/dreams';
case 'task':
return '/sync/tasks';
case 'progressLog':
return '/sync/progress-logs';
default:
return `/sync/${entityType}`;
}
}
// 检查网络是否可用
private async isNetworkAvailable(): Promise<boolean> {
try {
const netType = await network.getType();
return netType !== 0; // 0表示无网络连接
} catch (error) {
console.error(`检查网络状态失败: ${error instanceof Error ? error.message : String(error)}`);
return false;
}
}
// 释放资源
release(): void {
this.stopPeriodicSync();
if (this.networkObserver) {
network.unsubscribe(this.networkObserver);
}
}
}
// 使用示例
export async function saveAndSyncDream(dream: Dream): Promise<number> {
// 本地保存
const dreamId = await saveDreamLocally(dream);
// 添加到同步队列
const syncManager = DataSyncManager.getInstance();
syncManager.addChangeToSync('dream', { ...dream, id: dreamId });
return dreamId;
}
冲突解决策略
系统实现了智能冲突解决机制:
export enum ConflictResolutionStrategy {
LOCAL_WINS = 'LOCAL_WINS',
SERVER_WINS = 'SERVER_WINS',
MANUAL_RESOLVE = 'MANUAL_RESOLVE',
MERGE = 'MERGE'
}
export class ConflictResolver {
// 检测数据冲突
static detectConflict(localData: any, serverData: any): boolean {
return localData.updatedAt !== serverData.updatedAt;
}
// 解决冲突
static async resolveConflict(
entityType: string,
localData: any,
serverData: any,
strategy: ConflictResolutionStrategy = ConflictResolutionStrategy.MERGE
): Promise<any> {
console.info(`解决${entityType}冲突,策略: ${strategy}`);
switch (strategy) {
case ConflictResolutionStrategy.LOCAL_WINS:
return localData;
case ConflictResolutionStrategy.SERVER_WINS:
return serverData;
case ConflictResolutionStrategy.MERGE:
return this.mergeData(entityType, localData, serverData);
case ConflictResolutionStrategy.MANUAL_RESOLVE:
return await this.promptUserForResolution(localData, serverData);
default:
return serverData; // 默认以服务器为准
}
}
// 合并数据
private static mergeData(entityType: string, localData: any, serverData: any): any {
// 基本策略:保留最新的非空值
const merged = { ...serverData }; // 以服务器数据为基础
// 根据实体类型应用特定的合并逻辑
if (entityType === 'dream') {
// 如果本地更新时间更新,优先使用本地字段
if (new Date(localData.updatedAt) > new Date(serverData.updatedAt)) {
merged.title = localData.title || merged.title;
merged.description = localData.description || merged.description;
merged.category = localData.category ?? merged.category;
merged.targetDate = localData.targetDate || merged.targetDate;
merged.priority = localData.priority ?? merged.priority;
}
// 某些字段可能需要特殊处理
// 例如,进度取较大值
merged.progress = Math.max(localData.progress, serverData.progress);
}
return merged;
}
// 提示用户手动解决冲突
private static async promptUserForResolution(localData: any, serverData: any): Promise<any> {
return new Promise((resolve) => {
// 在实际应用中,应显示UI让用户选择或合并数据
AlertDialog.show({
title: '数据冲突',
message: '本地数据和服务器数据存在冲突,请选择要保留的版本:',
primaryButton: {
value: '使用本地版本',
action: () => {
resolve(localData);
}
},
secondaryButton: {
value: '使用服务器版本',
action: () => {
resolve(serverData);
}
}
});
});
}
}
数据缓存层
为提高应用性能,系统实现了高效的内存缓存:
export class MemoryCache<T> {
private cache: Map<string, T> = new Map();
private expiryTimes: Map<string, number> = new Map();
private defaultTTL: number; // 生存时间,以毫秒为单位
private maxSize: number; // 缓存最大项数
constructor(defaultTTLSeconds: number = 300, maxSize: number = 100) {
this.defaultTTL = defaultTTLSeconds * 1000;
this.maxSize = maxSize;
this.startCleanupTimer();
}
// 设置缓存项
set(key: string, value: T, ttlSeconds?: number): void {
// 如果缓存达到最大限制,移除最老项
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
this.removeOldest();
}
this.cache.set(key, value);
const expiry = Date.now() + (ttlSeconds ? ttlSeconds * 1000 : this.defaultTTL);
this.expiryTimes.set(key, expiry);
}
// 获取缓存项
get(key: string): T | undefined {
const value = this.cache.get(key);
if (value === undefined) {
return undefined;
}
const expiry = this.expiryTimes.get(key);
if (expiry && expiry < Date.now()) {
this.remove(key);
return undefined;
}
return value;
}
// 检查键是否存在
has(key: string): boolean {
if (!this.cache.has(key)) {
return false;
}
const expiry = this.expiryTimes.get(key);
if (expiry && expiry < Date.now()) {
this.remove(key);
return false;
}
return true;
}
// 移除缓存项
remove(key: string): void {
this.cache.delete(key);
this.expiryTimes.delete(key);
}
// 清除所有缓存
clear(): void {
this.cache.clear();
this.expiryTimes.clear();
}
// 移除过期项
private cleanup(): void {
const now = Date.now();
for (const [key, expiry] of this.expiryTimes.entries()) {
if (expiry < now) {
this.remove(key);
}
}
}
// 移除最老的缓存项
private removeOldest(): void {
if (this.cache.size === 0) return;
let oldestKey: string | null = null;
let oldestExpiry = Infinity;
for (const [key, expiry] of this.expiryTimes.entries()) {
if (expiry < oldestExpiry) {
oldestExpiry = expiry;
oldestKey = key;
}
}
if (oldestKey) {
this.remove(oldestKey);
}
}
// 启动定期清理过期项的定时器
private startCleanupTimer(): void {
// 每5分钟清理一次过期项
setInterval(() => this.cleanup(), 5 * 60 * 1000);
}
}
// 使用示例
const dreamCache = new MemoryCache<Dream>(600); // 10分钟过期
export async function getDreamById(dreamId: number): Promise<Dream> {
// 尝试从缓存获取
const cacheKey = `dream_${dreamId}`;
const cachedDream = dreamCache.get(cacheKey);
if (cachedDream) {
console.info(`从缓存获取梦想: ${dreamId}`);
return cachedDream;
}
// 从本地数据库查询
const dream = await queryDreamFromDb(dreamId);
// 添加到缓存
if (dream) {
dreamCache.set(cacheKey, dream);
}
return dream;
}
通过多层数据持久化策略,梦想生活规划师应用实现了高效可靠的数据管理,能够在各种网络环境下为用户提供一致的体验,同时确保用户数据的安全性和完整性。该系统的设计适应了移动应用的特殊需求,实现了高效的本地存取和智能的云端同步,为用户梦想管理提供了坚实的数据基础。
更多推荐
所有评论(0)