HarmonyOS 鸿蒙Next 使用用户首选项存取数据,存储数据的类型为对象时,重启app之后获取到的数据的类型变为了字符串

发布于 1周前 作者 zlyuanteng 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 使用用户首选项存取数据,存储数据的类型为对象时,重启app之后获取到的数据的类型变为了字符串

使用场景: 

1. 创建用户首选项实例preferences.getPreferences(context, name, (error: BusinessError, onePreference: preferences.Preferences) => { if (!error) { this.mPreferences = onePreference } })

2. 持久化数据 this.mPreferences.put(“user_info”, {“name”:“jock”}) 

3. 读取数据 let value = this.mPreferences.getSync(“user_info”, {}) 

 实际情况:

1. 在存储数据之后立即调用get方法,获取到的数据依然是object类型

2. 在重启app之后再次调用get方法,获取到的数据的类型就变为了string  期望的是可以返回实际的数据

2 回复

参考下这个demo:

Index.ets

~~~

import { PreferencesUtil } from './PreferencesUtil';

export class UserInfo {

  name: string = ''

}

[@Entry](/user/Entry)

[@Component](/user/Component)

struct Index {

  [@State](/user/State) message: string = 'Hello World';

  private preferencesUtil: PreferencesUtil = new PreferencesUtil()

  aboutToAppear(): void {

    this.preferencesUtil.loadPreference(getContext(this), 'aaa')

  }

  build() {

    Column() {

      Text('设置')

        .id('HelloWorld')

        .fontSize(50)

        .fontWeight(FontWeight.Bold)

        .alignRules({

          center: { anchor: '__container__', align: VerticalAlign.Center },

          middle: { anchor: '__container__', align: HorizontalAlign.Center }

        })

        .onClick(async () => {

          //1. 创建用户首选项实例

          await this.preferencesUtil.setPreference('aaa', 'user_info', { name: "jock" } as  UserInfo)

          let info = await this.preferencesUtil.getPreference('aaa', 'user_info',new UserInfo() ) as  UserInfo

          console.info(JSON.stringify(info.name))

          console.info(JSON.stringify(info))

        })

      Text('获取')

        .id('HelloWorld')

        .fontSize(50)

        .fontWeight(FontWeight.Bold)

        .alignRules({

          center: { anchor: '__container__', align: VerticalAlign.Center },

          middle: { anchor: '__container__', align: HorizontalAlign.Center }

        })

        .onClick(async () => {

          //1. 创建用户首选项实例

          let info = await this.preferencesUtil.getPreference('aaa', 'user_info',new UserInfo()) as  UserInfo

          console.info(JSON.stringify(info.name))

          console.info(JSON.stringify(info))

        })

    }

    .height('100%')

    .width('100%')

  }

}

~~~

PreferencesUtil.ets

~~~

import dataPreferences from '[@ohos](/user/ohos).data.preferences';

export class PreferencesUtil {

  private prefArr: Map<string, dataPreferences.Preferences> = new Map();

  /**

   * 初始化一个首选项实例

   *

   * [@param](/user/param) context

   * [@param](/user/param) name

   */

  loadPreference(context: Context, name: string) {

    dataPreferences.getPreferences(context, name)

      .then(preference => {

        this.prefArr.set(name, preference);

        console.log(`首选项${name}初始化成功`);

      })

      .catch((error: Error) => {

        console.log(`首选项${name}初始化失败:`, JSON.stringify(error));

      })

  }

  /**

   * 获取首选项实例对应键的值

   *

   * [@param](/user/param) name

   * [@param](/user/param) key

   * [@param](/user/param) defValue

   * [@returns](/user/returns) Promise<dataPreferences.ValueType>

   */

  async getPreference(name: string, key: string, defValue: dataPreferences.ValueType): Promise<dataPreferences.ValueType|undefined> {

    if (!this.prefArr.has(name)) {

      console.log(`首选项${name}尚未初始化`);

      return undefined;

    }

    let preference = this.prefArr.get(name);

    if (preference){

    try{

      let value = await preference?.get(key, defValue);

      console.log(`获取首选项${name}[key = ${key}]的值成功`);

      return value;

    } catch(e) {

      console.log(`获取首选项${name}[key = ${key}]的值失败:`, JSON.stringify(e));

    }

    }

    return undefined;

  }

  /**

   * 设置首选项实例对应键的值

   *

   * [@param](/user/param) name

   * [@param](/user/param) key

   * [@param](/user/param) value

   */

  async setPreference(name: string, key: string, value: dataPreferences.ValueType) {

    if (!this.prefArr.has(name)) {

      console.log(`首选项${name}尚未初始化`);

      return;

    }

    let preference = this.prefArr.get(name);

    try{

      await preference?.put(key, value);

      preference?.flush(); // 持久化

      console.log(`设置首选项${name}[key = ${key}, value = ${value}]的值成功`);

    } catch(e) {

      console.log(`设置首选项${name}[key = ${key}, value = ${value}]的值失败:`, JSON.stringify(e));

    }

  }

  /**

   * 删除首选项实例对应键的项

   *

   * [@param](/user/param) name

   * [@param](/user/param) key

   */

  async deletePreference(name: string, key: string) {

    if (!this.prefArr.has(name)) {

      console.log(`首选项${name}尚未初始化`);

      return;

    }

    let preference = this.prefArr.get(name);

    try{

      await preference?.delete(key);

      console.log(`删除首选项${name}[key = ${key}]成功`);

    } catch(e) {

      console.log(`删除首选项${name}[key = ${key}]失败:`, JSON.stringify(e));

    }

  }

}

在HarmonyOS鸿蒙Next系统中,若您在使用用户首选项(Preferences)来存储数据,并且发现存储的对象类型在重启应用后变成了字符串,这通常是由于数据类型序列化与反序列化的问题导致的。

HarmonyOS的用户首选项系统默认支持基本数据类型(如int, float, boolean等)和String类型的存储。对于自定义对象,您需要实现自定义的序列化与反序列化逻辑。这可能包括将对象转换为JSON字符串进行存储,并在读取时再将JSON字符串转换回对象。

检查以下几点:

  1. 确保在存储对象时,您已经将其转换为字符串(例如,使用JSON)。
  2. 在读取时,确保您正确地将字符串转换回了对象。
  3. 如果使用了第三方库来处理JSON,确保该库在您的项目中被正确集成和使用。

此外,确认您的代码中没有类型强制转换的错误,这可能导致数据在运行时被错误地解释。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。他们将能够提供更具体的帮助和指导,以解决您在使用HarmonyOS鸿蒙Next时遇到的问题。

回到顶部