HarmonyOS鸿蒙Next中Preferences持久化存储数组数据的正确方式

HarmonyOS鸿蒙Next中Preferences持久化存储数组数据的正确方式 使用Preferences存储数组时,直接存取导致数据丢失或类型错误:

// 错误:Preferences不支持直接存储数组
await preferences.put('myArray', [1, 2, 3]);
const arr = await preferences.get('myArray', []); // 返回undefined或错误
3 回复

原理解析

HarmonyOS的Preferences(首选项)存储支持的数据类型有限:

  • 支持:number、string、boolean、Array<number>、Array<string>、Array<boolean>
  • 不支持:复杂对象、嵌套数组、自定义类型

对于复杂数据结构,需要使用JSON序列化。

解决方案

封装存储工具类,使用JSON.stringify/parse处理:

import preferences from '@ohos.data.preferences';

class StorageUtil {
  private prefs: preferences.Preferences | null = null;
  
  async init(context: Context): Promise<void> {
    this.prefs = await preferences.getPreferences(context, 'app_storage');
  }
  
  // 存储字符串
  async setString(key: string, value: string): Promise<void> {
    if (!this.prefs) return;
    await this.prefs.put(key, value);
    await this.prefs.flush();
  }
  
  // 获取字符串
  async getString(key: string, defaultValue: string = ''): Promise<string> {
    if (!this.prefs) return defaultValue;
    const value = await this.prefs.get(key, defaultValue);
    return value as string;
  }
  
  // 同步获取(需要先初始化)
  getStringSync(key: string, defaultValue: string = ''): string {
    if (!this.prefs) return defaultValue;
    return this.prefs.getSync(key, defaultValue) as string;
  }
  
  // 存储数字
  async setNumber(key: string, value: number): Promise<void> {
    if (!this.prefs) return;
    await this.prefs.put(key, value);
    await this.prefs.flush();
  }
  
  getNumberSync(key: string, defaultValue: number = 0): number {
    if (!this.prefs) return defaultValue;
    return this.prefs.getSync(key, defaultValue) as number;
  }
}

export const storageUtil = new StorageUtil();

存储复杂数据示例

// 定义数据接口
interface FavoriteItem {
  id: string;
  title: string;
  addTime: number;
}

// 存储数组
async function saveFavorites(favorites: FavoriteItem[]): Promise<void> {
  const jsonStr = JSON.stringify(favorites);
  await storageUtil.setString('favorites', jsonStr);
}

// 读取数组
async function loadFavorites(): Promise<FavoriteItem[]> {
  const jsonStr = await storageUtil.getString('favorites', '[]');
  try {
    return JSON.parse(jsonStr) as FavoriteItem[];
  } catch (e) {
    return [];
  }
}

// 使用示例
@Component
struct FavoritePage {
  @State favoriteIds: string[] = [];
  
  async aboutToAppear(): Promise<void> {
    // 从持久化存储加载
    const savedStr = await storageUtil.getString('favorite_ids', '[]');
    try {
      this.favoriteIds = JSON.parse(savedStr) as string[];
    } catch (e) {
      this.favoriteIds = [];
    }
  }
  
  async toggleFavorite(id: string): Promise<void> {
    if (this.favoriteIds.includes(id)) {
      this.favoriteIds = this.favoriteIds.filter(i => i !== id);
    } else {
      this.favoriteIds = [...this.favoriteIds, id];
    }
    // 保存到持久化存储
    await storageUtil.setString('favorite_ids', JSON.stringify(this.favoriteIds));
  }
}

更多关于HarmonyOS鸿蒙Next中Preferences持久化存储数组数据的正确方式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙Next中,使用Preferences存储数组数据,需将数组转换为字符串或JSON格式。例如,使用JSON.stringify()将数组序列化为字符串后存入Preferences。读取时,通过JSON.parse()解析字符串还原为数组。这是鸿蒙应用数据持久化的标准方式。

在HarmonyOS Next中,Preferences确实不支持直接存储数组、对象等复杂数据类型。正确的做法是先将数组序列化为字符串(如JSON格式)再进行存储,读取时反序列化。

正确示例:

import { preferences, dataPreferences } from '@kit.ArkData';

// 1. 获取Preferences实例
let context: Context = ...; // 获取UIAbility上下文
let pref: preferences.Preferences = await dataPreferences.getPreferences(context, 'myStore');

// 2. 存储数组:序列化为JSON字符串
let myArray = [1, 2, 3];
await pref.put('myArray', JSON.stringify(myArray));
await pref.flush(); // 提交更改

// 3. 读取数组:获取字符串并反序列化
let arrayString = await pref.get('myArray', '[]'); // 默认值设为'[]'
let retrievedArray = JSON.parse(arrayString); // [1, 2, 3]

关键点:

  • 使用JSON.stringify()将数组转为字符串存储
  • 使用JSON.parse()将读取的字符串还原为数组
  • 设置默认值时也要用字符串格式(如'[]'
  • 对象等其他复杂数据同样需要序列化处理

注意事项:

  • 确保数据可序列化(避免循环引用)
  • 大量数据考虑使用关系型数据库
  • 简单键值对存储才用Preferences

这种方式能保证数组数据的完整性和类型正确性。

回到顶部