简介
为便于直接 cv,加快开发速度,减少学习成本,现提取 codelabs 案例中的重点实现部分代码,加以简要分析,有助于快速复制并直接实现对应效果
HarmonyOS 第一课 保存应用数据
GlobalContext
这里可以理解为 springboot 中在 application.yaml 中配置 mysql 连接
因为使用 preference 存储功能,必须提供一个唯一的上下文实例,每一个实例对应一个独立的 preference 存储区
GlobalContext
可以理解为一个全局的,供 preference 使用的上下文对象
下方代码采用惰性初始化的方式获取了一个单例对象
GlobalContext 对象拥有一个 map,我们的数据就都存储到该 map 里面,而 preference 就相当于帮助我们进行存储读取操作的桥梁
export class GlobalContext {
private constructor() {}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
// 初始化
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
// 获取对象中存储值的方法
getObject(value: string): Object | undefined {
return this._objects.get(value);
}
// 设置对象中值的方法
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}
PreferenceUtil
此部分代码比较长,现分段讲述,并在文末给出完整代码
数据库名与字段名
调用 Preference 是必须设置 PREFERENCES_NAME 来定义当前数据库的名称
此外还要定义我们需要执行存储的字段名称,因为案例是修改字体大小,所以这里就定义字段名称 KEY_APP_FONT_SIZE
const TAG = "[PreferencesUtil]";
const PREFERENCES_NAME = "myPreferences";
const KEY_APP_FONT_SIZE = "appFontSize";
数据库操作
这里可以简单理解为后端的 service 层
代码含义全部在注释内部呈现
export class PreferencesUtil {
// 创建preference数据库
// 根据上面我们创建的GlobalContext来设置
createFontPreferences(context: Context) {
let fontPreferences: Function = () => {
let preferences: Promise<dataPreferences.Preferences> =
dataPreferences.getPreferences(context, PREFERENCES_NAME);
return preferences;
};
// GlobalContext.getContext()获取单例对象
// setObject将我们的preference数据库存到该对象内,后续直接通过getFontPreferences来调用数据库
GlobalContext.getContext().setObject("getFontPreferences", fontPreferences);
}
// 保存默认字体大小
saveDefaultFontSize(fontSize: number) {
let getFontPreferences: Function = GlobalContext.getContext().getObject(
"getFontPreferences"
) as Function;
getFontPreferences()
.then((preferences: dataPreferences.Preferences) => {
preferences
.has(KEY_APP_FONT_SIZE)
.then(async (isExist: boolean) => {
Logger.info(TAG, "preferences has changeFontSize is " + isExist);
if (!isExist) {
await preferences.put(KEY_APP_FONT_SIZE, fontSize);
preferences.flush();
}
})
.catch((err: Error) => {
Logger.error(TAG, "Has the value failed with err: " + err);
});
})
.catch((err: Error) => {
Logger.error(TAG, "Get the preferences failed, err: " + err);
});
}
// 当字体大小改变后保存
saveChangeFontSize(fontSize: number) {
// 获取数据库的promise方法
let getFontPreferences: Function = GlobalContext.getContext().getObject(
"getFontPreferences"
) as Function;
// 使用promise风格依次处理
getFontPreferences()
.then(async (preferences: dataPreferences.Preferences) => {
await preferences.put(KEY_APP_FONT_SIZE, fontSize);
preferences.flush();
})
.catch((err: Error) => {
Logger.error(TAG, "put the preferences failed, err: " + err);
});
}
// 异步获取改变后的字体大小
async getChangeFontSize() {
let fontSize: number = 0;
let getFontPreferences: Function = GlobalContext.getContext().getObject(
"getFontPreferences"
) as Function;
fontSize = await (
await getFontPreferences()
).get(KEY_APP_FONT_SIZE, fontSize);
return fontSize;
}
// 删除改变后的字体大小
async deleteChangeFontSize() {
let getFontPreferences: Function = GlobalContext.getContext().getObject(
"getFontPreferences"
) as Function;
const preferences: dataPreferences.Preferences = await getFontPreferences();
let deleteValue = preferences.delete(KEY_APP_FONT_SIZE);
deleteValue
.then(() => {
Logger.info(TAG, "Succeeded in deleting the key appFontSize.");
})
.catch((err: Error) => {
Logger.error(
TAG,
"Failed to delete the key appFontSize. Cause: " + err
);
});
}
}
export default new PreferencesUtil();
实际调用
前面说过,定义 PreferencesUtil 可以理解为 service 层,那么这里就可以认为是 controller 层(这样比喻其实不算恰当,因为 ArkTS 是声明式 UI 语言,而目前主推的前后端分离是不会在 controller 里面定义页面渲染的)
比如,我们在主页面 onPageShow 钩子函数内,调用 PreferencesUtil 来获取我们的字体大小
HomePage {
changeFontSize: number = CommonConstants.SET_SIZE_NORMAL;
onPageShow() {
PreferencesUtil.getChangeFontSize().then((value) => {
this.changeFontSize = value;
Logger.info(TAG, 'Get the value of changeFontSize: ' + this.changeFontSize);
});
}
}
struct