HarmonyOS Next开发,使用Promise异步回调方式封装用户首选项(preferences)

目录

前言

版本说明:本文的API版本为12

一、业务场景

场景1(APP欢迎页):

 场景2(搜索功能):

场景3(存储token):

二、封装用户首选项API

1、创建首选项工具类(PreferencesUtil)

2、获取首选项实例

3、销毁首选项实例

4、从首选项实例中获取键对应的值

5、从首选项实例中写入数据

 6、new一下工具类,并导出

 三、完整文件代码

四、使用首选项工具类

附录


前言

        本专栏记录鸿蒙应用开发的一些知识,供鸿蒙开发者学习。笔者目前还是个小菜鸡,鸿蒙开发也是我看相关资料自学的,所以本文有些地方可能考虑不够周到,有些纰漏,就当抛砖引玉,还望读者海涵。目前HarmonyOS Next已经发布,API已更新至12,只有鸿蒙的开发者越来越多,才能更好的去改进HarmonyOS,去做好我们国人自己的系统,防止被别人卡脖子。本专栏适合初学者做一个入门,同时默认读者具备一定前端基础。本专栏的内容可以做一些课设,毕设之类的。但对于企业中的真实需求,可能考虑不够周到。因为笔者目前还没有工作(T_T)


         本文主要讲解用户首选项的封装。在鸿蒙应用开发中,用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。简单来说,就是可以存储数字类型、布尔类型、字符串类型及其对应的数组。Key要求非空,长度不超过80字节;Value的大小不超过8192字节。官方文档地址:用户首选项Preferences


版本说明:本文的API版本为12


一、业务场景

场景1(APP欢迎页):

        比如APP欢迎页,用户需要同意隐私政策,才可以继续访问APP(如下图)。Key-Value 键值型存储恰好满足这一业务需求。我们只需在用户点击同意时,用K-V保存用户这个操作行为,等下一次用户再点开APP,只需查看这个Key中是否有值,再判断用户是否可以访问APP即可。

 场景2(搜索功能):

        在搜索功能中,我们一般需要保存用户的搜索记录,并在页面中显示用户的最近搜索内容。而用户搜索记录,一般是字符串的形式,若干个搜索记录就是一个字符串数组。而用户首选项恰好可以存储字符串数组。

        

场景3(存储token):

        了解前后端分离开发的读者应该知道,token常用于用户的身份校验。当用户登录成功后,后端服务器会返回token,而前端在访问后端某些资源时,必须携带token用于校验身份。而token的存储,也可以用到用户首选项。


二、封装用户首选项API

        在项目中,为了代码的可维护性和可读性,不建议单独使用首选项。一般需封装成一个工具类,在需要时,调用工具类里的方法。

1、创建首选项工具类(PreferencesUtil)

import { preferences } from '@kit.ArkData'

class PreferenceUtil{

  // 首选项实例
  private pref: preferences.Preferences | null = null

}

2、获取首选项实例

        根据官方文档,想要获取首选项实例【getPreferences方法】,需要用到context上下文。而在官方文档中,这个context上下文,可以在EntryAbility的生命周期函数中,直接获取。

        所以我们这里把context上下文提出去,在EntryAbility的生命周期函数中,调用我们的初始化首选项方法。在方法里我们可以加点try-catch,提升代码的健壮性。

        *注:函数中的【CommonConstants.G_STORE】是一个字符串常量,是首选项的实例名称,CommonConstants类下存放着各种常量。在项目中,如果在多个地方使用同一个常量,推荐将他封装到常量类里面,这样代码的维护性会更好。

  /*
    * 初始化preferences实例
    * @context  应用上下文
   */
  async loadPreference(context: Context){
    try {
      this.pref = await preferences.getPreferences(context, CommonConstants.G_STORE)
      console.log(`preferences[${CommonConstants.G_STORE}]初始化成功`)
    } catch (err) {
      console.error(`preferences[${CommonConstants.G_STORE}]初始化失败`)
      console.error('err: ', JSON.stringify(err))
    }
  }

3、销毁首选项实例

        同样的,销毁首选项实例需要context上下文。我们这里也将context上下文提出去,在需要的地方,再调用销毁方法。

/*
    * 销毁preferences实例 - 缓存、持久化文件一并销毁
    * @context  应用上下文
   */
  async delPreference(context: Context){
    try {
      await preferences.deletePreferences(context, CommonConstants.G_STORE)
      console.log(`preferences[${CommonConstants.G_STORE}]销毁成功`)
    } catch (err) {
      console.error(`preferences[${CommonConstants.G_STORE}]销毁失败`)
      console.error('err: ', JSON.stringify(err))
    }
  }

4、从首选项实例中获取键对应的值

        想要获取首选项实例中,键对应的值,我们需要用到【get】方法,该方法由首选项实例调用。所以在取值时,我们需要先判断首选项是否初始化成功,即在EntryAbility的生命周期函数中,是否成功调用上文第2小点的【loadPreference】方法。

        调用首选项实例的【get】方法,根据官方文档,我们需要传入key--键,defaultValue--取值失败时,返回的值。我们将这两个参数提出去,由外部调用时提供。

  /*
    * 从preferences实例中获取键对应的值
    * @key            健
    * @defaultValue   获取失败时,返回的值
   */
  async getPreferenceValue(key: string, defaultValue: preferences.ValueType): Promise<preferences.ValueType>{

    let value: preferences.ValueType = defaultValue

    // 获取对应的值之前,先判断preferences是否初始化完成
    if (!this.pref) {
      console.error(`preferences[${CommonConstants.G_STORE}]尚未初始化!`)
      return value
    }

    try {
      value = await this.pref.get(key, defaultValue)
      console.log(`读取preferences[${key} = ${value}]成功`)
    } catch (err) {
      console.error(`读取preferences[${key}]失败 `, JSON.stringify(err))
    }

    return value
  }

5、从首选项实例中写入数据

        从首选项实例写入数据之前,我们同样需要判断首选项是否初始化成功。

        【put】方法仅仅是把key-value值写入内存中,并不做数据的持久化。也就是说,用户一旦退出APP,数据就没有了。而好处就是,响应时间快,因为是保存在内存里。

        【flush】方法则会将首选项实例持久化存储,用户即使退出APP,数据仍然存在。而坏处就是,由于持久化存储是存在磁盘里面,读取数据时,不可避免会有IO操作,数据响应较慢。

        是否使用【flush】方法,根据业务需要而定。这里使用【flush】方法。

/*
  * 从Preferences实例中写入数据
  * @key        健
  * @value      值
 */
  async putPreferenceValue(key: string, value: preferences.ValueType){

    // 写入数据之前,先判断preferences是否初始化完成
    if (!this.pref) {
      console.error(`preferences[${CommonConstants.G_STORE}]尚未初始化!`)
      return
    }

    try {
      await this.pref.put(key, value)
      // 持久化
      await this.pref.flush()
      console.log(`保存preferences[${key} = ${value}]成功`)
    } catch (err) {
      console.error(`保存preferences[${key} = ${value}]失败`, JSON.stringify(err))
    }

  }

 6、new一下工具类,并导出

const preferenceUtil = new PreferenceUtil()

export default preferenceUtil as PreferenceUtil

 三、完整文件代码

import { preferences } from '@kit.ArkData'
import { CommonConstants } from '../constants/CommonConstants'

class PreferenceUtil{

  // 首选项实例
  private pref: preferences.Preferences | null = null

  /*
    * 初始化preferences实例
    * @context  应用上下文
   */
  async loadPreference(context: Context){
    try {
      this.pref = await preferences.getPreferences(context, CommonConstants.G_STORE)
      console.log(`preferences[${CommonConstants.G_STORE}]初始化成功`)
    } catch (err) {
      console.error(`preferences[${CommonConstants.G_STORE}]初始化失败`)
      console.error('err: ', JSON.stringify(err))
    }
  }

  /*
    * 销毁preferences实例 - 缓存、持久化文件一并销毁
    * @context  应用上下文
   */
  async delPreference(context: Context){
    try {
      await preferences.deletePreferences(context, CommonConstants.G_STORE)
      console.log(`preferences[${CommonConstants.G_STORE}]销毁成功`)
    } catch (err) {
      console.error(`preferences[${CommonConstants.G_STORE}]销毁失败`)
      console.error('err: ', JSON.stringify(err))
    }
  }

  /*
    * 从preferences实例中获取键对应的值
    * @key            健
    * @defaultValue   获取失败时,返回的值
   */
  async getPreferenceValue(key: string, defaultValue: preferences.ValueType): Promise<preferences.ValueType>{

    let value: preferences.ValueType = defaultValue

    // 获取对应的值之前,先判断preferences是否初始化完成
    if (!this.pref) {
      console.error(`preferences[${CommonConstants.G_STORE}]尚未初始化!`)
      return value
    }

    try {
      value = await this.pref.get(key, defaultValue)
      console.log(`读取preferences[${key} = ${value}]成功`)
    } catch (err) {
      console.error(`读取preferences[${key}]失败 `, JSON.stringify(err))
    }

    return value
  }

  /*
  * 从Preferences实例中写入数据
  * @key        健
  * @value      值
 */
  async putPreferenceValue(key: string, value: preferences.ValueType){

    // 写入数据之前,先判断preferences是否初始化完成
    if (!this.pref) {
      console.error(`preferences[${CommonConstants.G_STORE}]尚未初始化!`)
      return
    }

    try {
      await this.pref.put(key, value)
      // 持久化
      await this.pref.flush()
      console.log(`保存preferences[${key} = ${value}]成功`)
    } catch (err) {
      console.error(`保存preferences[${key} = ${value}]失败`, JSON.stringify(err))
    }

  }

}

const preferenceUtil = new PreferenceUtil()

export default preferenceUtil as PreferenceUtil

 常量类

export class CommonConstants {
  
  static readonly G_STORE: string = 'GreenTreasureStore'

  static readonly TOKEN: string = 'TOKEN'

  static readonly NULL_TOKEN: string = null

}

四、使用首选项工具类

1、在EntryAbility的生命周期函数中,初始化工具类

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import PreferenceUtil from '../utils/PreferencesUtil';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');

    // 初始化preferences
    PreferenceUtil.loadPreference(this.context)

  }

  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');

    // 销毁preferences
    //PreferenceUtil.delPreference(this.context)

  }

  ......

  }
}

2、在项目需要的地方,使用首选项工具类 

import PreferenceUtil from '../utils/PreferencesUtil';
import { CommonConstants } from '../constants/CommonConstants'

const getToken = async () => {
  return await PreferenceUtil.getPreferenceValue(
    CommonConstants.TOKEN, CommonConstants.NULL_TOKEN
  )
}

附录

贴一张官方的图


        文章结束,如有纰漏还望指正。可以在评论区留下自己的想法。思想的碰撞是自我提升的催化剂,可以激发创新和进步。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值