背景介绍
最近在了解并跟着官方文档尝试做一个鸿蒙app 小demo的过程中对在app中保存数据遇到些问题 特此记录下来
这里的数据持久化以 Preferences为例子展开
废话不多说 这里直接上节目(官方提供的文档示例:) 以Stage模型为例
1.明确preferences的类型
import data_preferences from '@ohos.data.preferences';let preferences = null;class EntryAbility extends UIAbility {onWindowStageCreate(windowStage) {try {data_preferences.getPreferences(this.context, 'mystore', function (err, val) {if (err) {console.error("Failed to get preferences. code =" + err.code + ", message =" + err.message);return;}//将val的值赋值给preferences preferences = val;console.info("Succeeded in getting preferences.");})} catch (err) {console.error("Failed to get preferences. code =" + err.code + ", message =" + err.message);}}
}
到这里 但是当我们使用preferences来调用 val->Preferences的数据进行 get/put操作时 会发现根本没有提示 并且preferences的类型显示的是any类型 不是val所对应的类型
所以这里我们就要在初始化的时候明确的指明preferences的具体类型 鼠标放在val的变量上 按住ctrl 就会发现 (parameter) val: data_preferences.Preferences 这一行 明确指出了val的具体类型
依葫芦画瓢
所以 我们的preferces变量的声明就可以写为:
export var preferences:data_preferences.Preferences = null;
这样我们就可以在当前类中进行随意的操作啦
当然这只是第一步 当我们进行sp操作的时候 往往都是在具体的页面中进行CRUD的 那如何在具体的页面中持有Sp呢?
2.在具体的页面中持有Preferences引用
首先第一步尝试在页面中引入EntryAbility中我们声明的变量
坑点:EntryAbility中的preferences一定要加 export不然外部引用不到
import {preferences} from '../entryability/EntryAbility'TabContent() {Stack() {Image($r('app.media.guide_page_four_bg')).objectFit(ImageFit.Auto)RelativeContainer() {Column() {Image($r('app.media.guide_page_four_text')).objectFit(ImageFit.Contain).width('80%')Image($r('app.media.guide_page_four')).objectFit(ImageFit.Auto).width('100%').margin({ top: 10 })Image($r('app.media.guide_page_four_start')).objectFit(ImageFit.Auto).width(100).height(45).margin({ top: 10 }).onClick(()=>{try {preferences.put('first_splash', 'yes', (err) => {if (err) {console.error(`Failed to put first_splash data. Code:${err.code}, message:${err.message}`);return;}console.info('Succeeded in putting first_splash data.');})} catch (err) {console.error(`Failed to put data. first_splash Code: ${err.code},message:${err.message}`);}try {preferences.flush((err) => {if (err) {console.error(`Failed to flush first_splash. Code:${err.code}, message:${err.message}`);return;}console.info('Succeeded in flushing. first_splash');})} catch (err) {console.error(`Failed to flush first_splash. Code:${err.code}, message:${err.message}`);}try {preferences.get('first_splash', 'default', (err, val) => {if (err) {console.error(`Failed to get value of 'startup'. Code:${err.code}, message:${err.message}`);return;}console.info(`Succeeded in getting value of 'startup'. val: ${val}.`);})} catch (err) {console.error(`Failed to get value of 'startup'. Code:${err.code}, message:${err.message}`);}})}.width('60%').height('80%').margin({ top: '20%' }).justifyContent(FlexAlign.SpaceBetween).alignRules({top: { anchor: '__container__', align: VerticalAlign.Top },middle: { anchor: '__container__', align: HorizontalAlign.Center },}).id("centerCoverFour")Text("跳过").id("skipFour").alignRules({left: { anchor: 'centerCoverFour', align: HorizontalAlign.End },bottom: { anchor: 'centerCoverFour', align: VerticalAlign.Bottom }}).fontSize(16).fontColor(Color.White)}.width('100%').height('100%')}}
sp的具体主要逻辑都在onClick中了
具体的操作Log如下:
ok 到这里就成功啦
3.应用重新启动后持久化数据丢失
场景:在第一次启动后将数据保存完毕之后 清除后台任务重新进入 读取数据正常 deveco中点击重新运行 内存中保存的相应文件被删除
原因:DevEco每次重新启动应用时都是卸载了之前的应用后重新部署,因此相关信息会被清除。
解决方案:
Build->Edit Configurations->勾选 keep application data