HarmonyOS鸿蒙Next中Preferences数据持久化存储怎么使用?数据写入后读取为空

HarmonyOS鸿蒙Next中Preferences数据持久化存储怎么使用?数据写入后读取为空 问题描述

  • HarmonyOS 5.0,DevEco Studio 5.0
  • 使用Preferences存储用户设置数据,但重启应用后数据丢失
  • 代码如下:
import { preferences } from '@kit.ArkData'

// 写入数据
const pref = await preferences.getPreferences(context, 'settings')
await pref.put('username', '张三')
// 重启后读取为空

希望了解Preferences的正确使用方法,确保数据能持久化保存


更多关于HarmonyOS鸿蒙Next中Preferences数据持久化存储怎么使用?数据写入后读取为空的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

写入数据后没有调用 flush() 方法! Preferences 的数据修改是在内存中进行的,必须调用 flush() 才会写入磁盘。

1. 正确的写入方式

import { preferences } from '@kit.ArkData'

// 写入数据 - 必须调用 flush()
const pref = await preferences.getPreferences(context, 'settings')
await pref.put('username', '张三')
await pref.put('age', 25)
await pref.flush()  // 关键!必须调用才会持久化

2. 完整的数据存储服务封装

import { preferences } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

class DataStore {
  private static instance: DataStore
  private dataStore: preferences.Preferences | null = null
  private context: common.UIAbilityContext | null = null
  
  static getInstance(): DataStore {
    if (!DataStore.instance) {
      DataStore.instance = new DataStore()
    }
    return DataStore.instance
  }
  
  // 初始化(在EntryAbility中调用)
  async init(context: common.UIAbilityContext): Promise<void> {
    this.context = context
    this.dataStore = await preferences.getPreferences(context, 'app_data')
  }
  
  // 存储字符串
  async putString(key: string, value: string): Promise<void> {
    await this.dataStore?.put(key, value)
    await this.dataStore?.flush()  // 必须调用!
  }
  
  // 读取字符串
  async getString(key: string, defaultValue: string = ''): Promise<string> {
    return await this.dataStore?.get(key, defaultValue) as string
  }
  
  // 存储数字
  async putNumber(key: string, value: number): Promise<void> {
    await this.dataStore?.put(key, value)
    await this.dataStore?.flush()
  }
  
  // 读取数字
  async getNumber(key: string, defaultValue: number = 0): Promise<number> {
    return await this.dataStore?.get(key, defaultValue) as number
  }
  
  // 存储布尔值
  async putBoolean(key: string, value: boolean): Promise<void> {
    await this.dataStore?.put(key, value)
    await this.dataStore?.flush()
  }
  
  // 读取布尔值
  async getBoolean(key: string, defaultValue: boolean = false): Promise<boolean> {
    return await this.dataStore?.get(key, defaultValue) as boolean
  }
  
  // 存储对象(JSON序列化)
  async putObject<T>(key: string, value: T): Promise<void> {
    const json = JSON.stringify(value)
    await this.dataStore?.put(key, json)
    await this.dataStore?.flush()
  }
  
  // 读取对象
  async getObject<T>(key: string, defaultValue: T): Promise<T> {
    const json = await this.dataStore?.get(key, '') as string
    if (json) {
      try {
        return JSON.parse(json) as T
      } catch (e) {
        return defaultValue
      }
    }
    return defaultValue
  }
  
  // 删除数据
  async delete(key: string): Promise<void> {
    await this.dataStore?.delete(key)
    await this.dataStore?.flush()
  }
  
  // 清空所有数据
  async clear(): Promise<void> {
    await this.dataStore?.clear()
    await this.dataStore?.flush()
  }
  
  // 检查key是否存在
  async has(key: string): Promise<boolean> {
    return await this.dataStore?.has(key) ?? false
  }
}

export const dataStore = DataStore.getInstance()

3. 在EntryAbility中初始化

import { dataStore } from '../utils/DataStore'

export default class EntryAbility extends UIAbility {
  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    // 初始化数据存储
    await dataStore.init(this.context)
  }
}

4. 在页面中使用

import { dataStore } from '../utils/DataStore'

@Entry
@Component
struct SettingsPage {
  @State username: string = ''
  @State darkMode: boolean = false
  
  async aboutToAppear(): Promise<void> {
    // 读取保存的设置
    this.username = await dataStore.getString('username', '未设置')
    this.darkMode = await dataStore.getBoolean('darkMode', false)
  }
  
  build() {
    Column({ space: 16 }) {
      // 用户名设置
      Row() {
        Text('用户名')
        TextInput({ text: this.username })
          .onChange(async (value) => {
            this.username = value
            await dataStore.putString('username', value)
          })
      }
      
      // 深色模式开关
      Row() {
        Text('深色模式')
        Toggle({ isOn: this.darkMode })
          .onChange(async (isOn) => {
            this.darkMode = isOn
            await dataStore.putBoolean('darkMode', isOn)
          })
      }
    }
    .padding(16)
  }
}

5. 存储复杂对象

interface UserSettings {
  theme: string
  fontSize: number
  notifications: boolean
  language: string
}

// 存储对象
const settings: UserSettings = {
  theme: 'dark',
  fontSize: 16,
  notifications: true,
  language: 'zh-CN'
}
await dataStore.putObject('userSettings', settings)

// 读取对象
const savedSettings = await dataStore.getObject<UserSettings>('userSettings', {
  theme: 'light',
  fontSize: 14,
  notifications: false,
  language: 'en'
})

更多关于HarmonyOS鸿蒙Next中Preferences数据持久化存储怎么使用?数据写入后读取为空的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,使用Preferences进行数据持久化存储时,写入后读取为空通常是因为未正确调用flush或commit方法将数据同步到磁盘。Preferences采用异步写入机制,数据先缓存在内存中。

确保写入操作后调用flush()方法立即同步,或使用commit()方法提交更改。读取时需使用相同的Preferences实例,并确保文件路径和名称一致。检查读写操作是否在同一进程内,跨进程访问需要额外配置。

在HarmonyOS Next中,使用@kit.ArkDatapreferences进行数据持久化,写入后读取为空或重启丢失,通常是因为没有正确提交数据。put方法仅将数据写入内存缓存,必须调用flush()flushSync()方法将缓存数据异步或同步写入磁盘文件。

根据你的代码,修正后的核心步骤如下:

  1. 获取Preferences实例:使用getPreferences获取指定名称的实例。
  2. 写入数据:使用put()方法写入键值对。
  3. 提交数据(关键步骤):调用flush()方法将数据持久化到文件。这是确保数据在重启后仍可读取的必要操作。
  4. 读取数据:使用get()方法读取数据。

以下是修正后的示例代码:

import { preferences } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';

// 1. 获取Preferences实例
let pref = await preferences.getPreferences(context, 'settings');

// 2. 写入数据
try {
  await pref.put('username', '张三');
  // 3. 关键:提交数据到磁盘
  await pref.flush();
  console.log('数据写入并提交成功');
} catch (err) {
  const error = err as BusinessError;
  console.error(`写入失败,错误码:${error.code}, 信息:${error.message}`);
}

// 4. 读取数据(例如在应用重启后)
try {
  let value = await pref.get('username', '默认值');
  console.log(`读取到的用户名: ${value}`);
} catch (err) {
  const error = err as BusinessError;
  console.error(`读取失败,错误码:${error.code}, 信息:${error.message}`);
}

关键点说明:

  • flush()是必须的put()操作后,数据仅存在于内存中。调用flush()会立即将内存中的所有更改写入持久化文件。你也可以使用flushSync()进行同步提交。
  • 数据存储位置:数据最终会以文件形式保存在应用沙箱目录下(例如/data/storage/el2/base/haps/entry/files/settings),因此重启应用后可以读取。
  • 错误处理:建议对putflushget等操作进行try-catch,以捕获可能出现的BusinessError(如I/O错误)。

确保在每次调用put()方法修改数据后,都跟随一个flush()调用,即可解决数据丢失问题。

回到顶部