鸿蒙preference数据缓存进阶用法实现增删改查

2025-01-12 20:33:20
68次阅读
0个评论
最后修改时间:2025-01-12 20:44:42

前言导读

最近在看这个数据缓存,然后也是群友一个问题一直卡着,到今天才有给群友处理, 今天主要分享的时候

鸿蒙用户首选项缓存数据 进阶用法 实现我们的增删改查

效果图

  • 增加数据

image-20250112192716789

  • 查询数据

image-20250112192813796

  • 更新数据

image-20250112193024189

image-20250112193324129

  • 删除数据 删除下标为2的数据

image-20250112193035940

image-20250112193045843

具体实现:

PreferencesUtil 工具类实现
import Logger from './Logger'
import common from '@ohos.app.ability.common'
import { preferences } from '@kit.ArkData'

/***
 *
 * 创建人:xuqing
 * 创建时间:2024年7月15日12:38:29
 * 类说明:preference 工具类
 *
 *
 */



let preference: preferences.Preferences | undefined = undefined
const context = getContext(this) as common.UIAbilityContext

export class PreferencesUtil {
  private readonly TAG: string = 'PreferenceUtil';

  writeString(key: string, value?: string) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readString(key: string, defaultValue?: string): string | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, defaultValue)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    return value as string | undefined
  }

  writeArrayString(key: string, value?: Array<string>) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readArrayString(key: string, defaultValue?: Array<string>): Array<string> | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, defaultValue)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    return value as Array<string> | undefined
  }

  writeNumber(key: string, value?: number) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readNumber(key: string, defaultValue?: number): number | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, defaultValue)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    return value as number | undefined
  }

  writeArrayNumber(key: string, value?: Array<number>) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readArrayNumber(key: string, defaultValue?: Array<number>): Array<number> | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, defaultValue)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    return value as Array<number> | undefined
  }

  writeBoolean(key: string, value?: boolean) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readBoolean(key: string, defaultValue?: boolean): boolean | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, defaultValue)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    return value as boolean | undefined
  }

  writeArrayBoolean(key: string, value?: Array<boolean>) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readArrayBoolean(key: string, defaultValue?: Array<boolean>): Array<boolean> | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, defaultValue)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    return value as Array<boolean> | undefined
  }

  writeObject(key: string, value?: object) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.putSync(key, value)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to write value, cause:' + e)
    }
    preference!!.flush()
  }

  readObject<T>(key: string): T | undefined {
    if (preference === undefined) {
      this.getPreferences()
    }
    let value: preferences.ValueType | undefined = undefined
    try {
      value = preference!!.getSync(key, undefined)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to read value, cause:' + e)
    }
    if (value === undefined) {
      return undefined
    }else {
      return value as T
    }
  }

  delete(key: string) {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.deleteSync(key)
    } catch (e) {
      Logger.error(this.TAG, 'Failed to delete, cause:' + e)
    }
    preference!!.flush()
  }

  clear() {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.clearSync()
    } catch (e) {
      Logger.error(this.TAG, 'Failed to clear, cause:' + e)
    }
    preference!!.flush()
  }

  flush() {
    if (preference === undefined) {
      this.getPreferences()
    }
    try {
      preference!!.flush()
    } catch (e) {
      Logger.error(this.TAG, 'Failed to flush, cause:' + e)
    }
  }

  private getPreferences() {
    try {

      let options: preferences.Options = { name:'myStore' };
      preference = preferences.getPreferencesSync(context, options);
    } catch (e) {
      Logger.error(this.TAG, 'Failed to get preferences, cause:' + e)
    }
  }

  private deletePreferences() {
    try {
      preference?.deleteSync('myStore')
    } catch (e) {
      Logger.error(this.TAG, 'Failed to delete preferences, cause:' + e)
    }
    preference = undefined
  }
}



export default new PreferencesUtil()

增加数据

我们观察源码我们可以发现 Preferences 并不支持存储对象数据 我们只需要把我们的数据存住在对象中 多条数据添加到数组里面 然后转成json字符串 然后存住json字符串到我们的缓存中即可

adduserInfo() {
  let getid:number|undefined=PreferencesUtil.readNumber("id",0);
  if (this.accout != '' && this.password != ''&&getid!=undefined) {
    let contentdata: UserInfo = {
      username: this.accout,
      password: this.password,
      id: getid
    }
    this.userdatalist.push(contentdata)
    getid++;
    PreferencesUtil.writeString("userdata",JSON.stringify(this.userdatalist));
    PreferencesUtil.writeNumber("id",getid);
    this.showToast("存储数据成功")
  }else{
    this.showToast("需要存储的数据输入能为空")
  }
}
  • 查询数据

查询数据也是类似的做法 我们获取到是一个json数组,我们需要通过使用 JSON.parse(getdatajson) as UserInfo[] 讲我们查询的数据欢迎成我们数组然后显示在我们的list组件上面

/***
 * 查询数据
 */
queryuserInfo() {
  let getdatajson:string|undefined=PreferencesUtil.readString("userdata",'');
  console.log("getdatajson"+getdatajson)
  if(getdatajson!=undefined&&getdatajson!=''){
    this.getdatalist=JSON.parse(getdatajson) as UserInfo[];
    this.uidatalist=this.getdatalist;
    this.showToast("查询数据成功")
  }else{
    this.showToast("本地没有缓存数据")
  }
}
  • 更新数据

更新数据 我们需要先讲我们查询的数据删除 然后更新一个新的对象到我们的数组里面 然后刷新我们的缓存

/***
 * 修改数据
 */
updateUserInfo(){
  let getdatajson:string|undefined=PreferencesUtil.readString("userdata",'');
  if(getdatajson!=undefined&&getdatajson!=''){
   let  getdatalist:UserInfo[]=JSON.parse(getdatajson) as UserInfo[];
    for (let index = 0; index < getdatalist.length; index++) {
      let userinfo:UserInfo=getdatalist[index];
      if(index===2){
      //  this.getdatalist.reverse(userinfo)
        let contentdata: UserInfo = {
          username: "更新的账户17387272",
          password: "更新的密码13432332",
          id: userinfo.id
        }
      //  getdatalist.splice(index,1);

          getdatalist.push(contentdata)
          PreferencesUtil.writeString("userdata",JSON.stringify(this.getdatalist));
          this.showToast("更新数据成功")
          break;
        }

      }
  }else{
    this.showToast("本地没有缓存数据")
  }
}
  • 删除数据

我们需要通过for循环查询到对象然后获取对象里面的id属性和我们需要删除的数据进行对比 如果想等我们就删除即可然后刷新缓存

/***
 * 删除数据
 */
deleteUserInfo(deletedata:number){
  let getdatajson:string|undefined=PreferencesUtil.readString("userdata",'');
  if(getdatajson!=undefined&&getdatajson!=''){
    this.getdatalist=JSON.parse(getdatajson) as UserInfo[];
    for (let index = 0; index < this.getdatalist.length; index++) {
      let userinfo:UserInfo=this.getdatalist[index];
      if(userinfo.id==deletedata){
        this.getdatalist.splice(index,1);
        PreferencesUtil.writeString("userdata",JSON.stringify(this.getdatalist));
        this.showToast("删除数据成功")
        break;
      }
    }
  }else{
    this.showToast("本地没有缓存数据")
  }

ui部分代码实现

build() {

    Column({ space: 10 }) {
      Row() {
        Text('账号').blackTextStyle()
        TextInput({ placeholder: '请输入账号' })
          .maxLength(12)
          .type(InputType.Normal)
          .inputStyle()
          .onChange((value: string) => {
            this.accout = value;
          })
          .margin({ left: 20 })

      }.justifyContent(FlexAlign.SpaceBetween)
      .width('100%')
      .margin({ top: 8 })

      Line().lineStyle().margin({ left: 80, right: 10 })

      Row() {
        Text('密码').blackTextStyle()
        TextInput({ placeholder: '请输入密码' })
          .maxLength(12)
          .type(InputType.Password)
          .inputStyle()
          .onChange((value: string) => {
            this.password = value;
          })
          .margin({ left: 20 })
      }.justifyContent(FlexAlign.SpaceBetween)
      .width('100%')
      .margin({ top: 8 })

      Line().lineStyle().margin({ left: 80, right: 10 })


      Row({ space: 10 }) {
        Button("增加数据")
          .onClick(() => {
            this.adduserInfo();
          }).layoutWeight(1).margin({ left: 20 })
        Button("修改数据")
          .onClick(() => {
            this.updateUserInfo()
          }).layoutWeight(1).margin({ right: 20 })
      }.width("100%").height(50).justifyContent(FlexAlign.Center)

      Row({ space: 10 }) {

        Button("查询数据")
          .onClick(() => {
            this.queryuserInfo()

          }).layoutWeight(1).margin({ left: 20 })

        Button("删除数据")
          .onClick(() => {
            this.deleteUserInfo(1)
          }).layoutWeight(1).margin({ right: 20 })
      }.width("100%").height(50).justifyContent(FlexAlign.Center)
      this.getlistview();
    }.height("100%")
    .width("100%")
    .backgroundColor($r('app.color.background'))
    .padding({
      left: 12,
      right: 12,
      bottom: 24
    })


}

list列表实现

  @Builder
  private  getlistview(){

    List({ initialIndex: 0, space: 5 }) {
      ForEach(this.uidatalist, (user: UserInfo, index: number) => {
        ListItem() {
          Row() {
            Column() {
              Image($r('app.media.startIcon')).width(50).height(50)
            }.layoutWeight(2)

            Column() {
              Text(`ID: ${user.id}`).width('100%').padding({left: 10})
              Text(`账号: ${user.username}`).width('100%').padding({left: 10})
              Text(`密码:${user.password}`).width('100%').padding({left: 10})
            }.layoutWeight(8)
          }
          .alignItems(VerticalAlign.Center)
          .width('100%')
        }
        .height(80)
        .width('100%')
        .backgroundColor(0xF1F3F5)
        .onClick(()=>{


        })

      }, (item: UserInfo, index: number) => index.toString())
    }
    .height('100%')
    .width('100%')
    .margin({top:20})

  }
}

最后总结:

上面的做法确实使用Preferences 用户首选项来实现我们的数据的增 删 改 查 但是我们在面对数据量大的时候· 我们还是不推荐这种做法因为官方文档有说明最好要存储过多数据会导致app的体积过大 如果数据量过大我们推荐 关系型数据库也就我们同常说的sqlite 来存储。今天的文章讲到这里, 如果觉得文章还不错可以给我一个一键三连。 有兴趣的 关注我B站教程 了解更多鸿蒙开发的知识 可以关注坚果派公众号 。 谢谢

课程地址

www.bilibili.com/cheese/play…

项目内容:

1 常用布局组件的学习
2 网络请求工具类封装
3 arkui 生命周期启动流程
4 日志工具类的封装
5 自定义组合组件的封装
6 路由导航跳转的使用
7 本地地数据的缓存 以及缓存工具类的封装
8 欢迎页面的实现
9 登录案例和自动登录效果实现
10 请求网络数据分页上拉加载 下拉刷新的实现
11 list数据懒加载实现
12 webview组件的使用

如果使用更多好用的鸿蒙next三方库

友情链接

harmony-utils 一款功能丰富且极易上手的HarmonyOS工具库,借助众多实用工具类,致力于助力开发者迅速构建鸿蒙应用,能够满足各种不同的开发需求。

harmony-dialog 一款极为简单易用的零侵入弹窗,仅需一行代码即可轻松实现,无论在何处都能够轻松弹出。

收藏00

登录 后评论。没有帐号? 注册 一个。