
回复
@TOC
一个本地应用,做一个收藏功能,要求收藏的内容,下次打开App的时候,还可以看到。
本地缓存
轻量级缓存SharedPreferences的实现
首先要解决下面这几个问题,什么时候存、什么时候取,如何存,以及应用内数据如何同步的问题。
我们需要有一个管理缓存的单例类,处理存、取、添加、修改、删除等操作。所以大概情况下,我们要先有下面这样一个结构的类,用来管理这一堆事情。
import { common } from '@kit.AbilityKit'
import { preferences } from '@kit.ArkData'
import { Country } from './DataModel'
/**
* 收藏数据管理
*/
export class CollectDataManager {
private static instance: CollectDataManager;
public collectItems: Array<Country> = []
private myStore:string = 'com.silence.flagCard';
private itemsKey: string = 'flagCard'
private static context: common.UIAbilityContext; // 应用上下文
// 私有构造函数
private constructor() {}
// 初始化上下文(需在应用启动时调用)
public static init(context: common.UIAbilityContext): void {
CollectDataManager.context = context;
}
// 获取单例实例
public static getInstance(): CollectDataManager {
if (!CollectDataManager.instance) {
if (!CollectDataManager.context) {
throw new Error('Context not initialized! Call PreferencesUtil.init() first.');
}
CollectDataManager.instance = new CollectDataManager();
}
return CollectDataManager.instance;
}
/**
* 加载缓存数据
*/
public async loadData() {}
/**
* 加载缓存数据
*/
public async loadData() {
try {
let pref = await preferences.getPreferences(CollectDataManager.context, this.myStore);
let itemsJson = await pref.get(this.itemsKey, '');
let itemsData = JSON.parse(itemsJson.toString()) as Array<Country>
this.collectItems = itemsData;
} catch (error) {
console.error('加载数据失败:', error)
this.collectItems = []
}
}
/**
* 保存缓存数据
*/
async saveData() {
try {
let itemsJson = JSON.stringify(this.collectItems)
let pref = await preferences.getPreferences(CollectDataManager.context, this.myStore);
await pref.put(this.itemsKey, itemsJson)
await pref.flush()
} catch (error) {
console.error('保存数据失败:', error)
}
}
/**
* 更新数据
* @param item
*/
updateItem(item: Country) {}
/**
* 删除数据
* @param id
*/
deleteItem(id: number) {}
/**
* 获取所有收藏数据
* @returns
*/
getAllItems(): Array<Country> {
return this.collectItems
}
/**
* 通过id获取收藏数据item
* @returns
*/
getItemById(id: number): Country | undefined{
return this.collectItems.find(item => item.id == id)
}
}
应用销毁之前,要将收藏的数据存到缓存文件中。我是建议在入口EntryAbility中onDestroy()方法中存储数据。
onDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
/// 保存数据
CollectDataManager.getInstance().saveData();
}
应用打开的时候,要将缓存的数据取出来。在收藏页面展示出来。我是建议在入口EntryAbility中onCreate()中初始化数据管理的单例类和获取数据。
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
/// 初始化轻量级缓存
CollectDataManager.init(this.context);
CollectDataManager.getInstance().loadData();
}
这里其实设计三个问题,添加数据、修改数据、删除数据。
/**
* 添加数据
* @param item
*/
addItem(item: Country) {
/// 需要去重处理
if(this.getItemById(item.id)){
return;
}
this.collectItems.push(item)
this.saveData()
}
/**
* 更新数据
* @param item
*/
updateItem(item: Country) {
// 判断是否存在
const index = this.collectItems.findIndex(i => i.id === item.id)
if (index !== -1) {
this.collectItems[index] = item
this.saveData()
}
}
/**
* 删除数据
* @param id
*/
deleteItem(id: number) {
// 判断是否存在
const index = this.collectItems.findIndex(i => i.id === id)
if (index !== -1) {
this.collectItems.splice(index, 1)
this.saveData()
}
}
需要借助修饰词 @ObservedV2 对类进行装饰,对需要数据变化,全局UI变化的collectItems使用@Trace进行装饰。修改如下。
/**
* 收藏数据管理
*/
@ObservedV2
export class CollectDataManager {
private static instance: CollectDataManager;
@Trace
public collectItems: Array<Country> = []
......
/**
* 我的收藏页面
*/
@Component
export struct CollectPage {
// 获取收藏列表
@State myCollectItems:Country[] = CollectDataManager.getInstance().collectItems;
......
/// 验证是已经收藏
this.isFavorite = CollectDataManager.getInstance().getItemById(this.country.id) != undefined;
if(this.isFavorite){
CollectDataManager.getInstance().deleteItem(this.country.id);
}else{
CollectDataManager.getInstance().addItem(this.country);
}