HarmonyOS 鸿蒙Next中preferences为什么获取不到值,得到是undefined
HarmonyOS 鸿蒙Next中preferences为什么获取不到值,得到是undefined
封装的
import { preferences } from "@kit.ArkData"
import { common } from '@kit.AbilityKit'
import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from "@kit.BasicServicesKit";
import { JSON } from "@kit.ArkTS";
const context = getContext(this) as common.UIAbilityContext
//本地存储
let dataPreference: preferences.Preferences | null = null;
export class StoreUtil {
// private static dataPreference: preferences.Preferences | null = null;
public static async init(){
try{
// const context = getContext() as common.UIAbilityContext
dataPreference = await preferences.getPreferences(context, 'userStore');
console.info('success getPreferences' + JSON.stringify(dataPreference))
}catch (e) {
console.log('第一步就报错'+e)
}
// dataPreference = preferences.getPreferences(context, 'userStore');
// return dataPreference
}
public static async put(key:string,value:string){
console.log(key,value)
// 如果不存在则初始化
if(JSON.stringify(dataPreference)==="{}"){
console.log('对象内容'+ JSON.stringify(dataPreference) )
StoreUtil.init()
}
//添加数据
try{
// dataPreference?.put('startup', 'auto').then(() => {
// console.info("Succeeded in putting value of 'startup'.");
// }).catch((err: BusinessError) => {
// console.error("Failed to put value of 'startup'. code =" + err.code + ", message =" + err.message);
// })
dataPreference?.putSync(key,value)
dataPreference?.flushSync()
console.log('-------------执行----------------')
}catch (e){
console.log('添加错误')
}
}
public static async get(key:string){
console.log(key)
if(JSON.stringify(dataPreference)==="{}"){
console.log('未初始化')
console.log('类型'+ typeof dataPreference)
StoreUtil.init()
}
//获取数据
dataPreference?.getSync(key,'default')
}
public static async delete(key:string){
if(!dataPreference){
console.log('未初始化')
StoreUtil.init()
}
//删除数据
dataPreference?.deleteSync(key)
dataPreference?.flushSync()
}
}
//button按钮 存储 用户信息
StoreUtil.put('userdata','1231231')
在首页获取到的值是undefined
let userdata:preferences.ValueType = StoreUtil.get('userdata').then(res=>{
console.log('-------------首页----------'+res)
})
模拟器版本5.1.1
更多关于HarmonyOS 鸿蒙Next中preferences为什么获取不到值,得到是undefined的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你的Preferences是异步初始化的,需等待初始化完成。所有需要 awat StoreUtil.init() ,
get 方法也缺少返回值,需要return
return dataPreference?.getSync(key,'default')

更多关于HarmonyOS 鸿蒙Next中preferences为什么获取不到值,得到是undefined的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
init()方法没有等待
-
未等待异步初始化完成
init() 方法是异步操作,但代码中直接调用 StoreUtil.put() 时未确保初始化已完成。建议增加初始化状态判断:private static isInitialized = false; public static async init() { if (this.isInitialized) return; try { dataPreference = await preferences.getPreferences(context, 'userStore'); this.isInitialized = true; } catch (e) { /* 错误处理 */ } }
可以存,就是返回值是字符串,而转成对象时,却无法获取到键值对,取到是undefined,
- StoreUtil类put方法中初始化Preferences实例判断不正确,dataPreference初始设置为null,使用
JSON.stringify(dataPreference) === '{}'固定返回为false,无法进入Preferences实例初始化逻辑。需修改如下:
// 如果不存在则初始化
if (!dataPreference || JSON.stringify(dataPreference) === '{}') {
StoreUtil.init()
}
- StoreUtil类init方法中初始化Preference实例建议使用同步方法,后续的插入、查询、删除都需先确保实例初始化完成。
public static async init() {
try {
dataPreference = preferences.getPreferencesSync(context, { name: 'testStore' });
console.info('success getPreferences' + JSON.stringify(dataPreference))
} catch (e) {
console.error('第一步就报错' + e)
}
}
- StoreUtil类get方法从Preference中读取数据后未将数据返回出去,需增加return。
public static async get(key: string) {
// 如果不存在则初始化
if (!dataPreference || JSON.stringify(dataPreference) === '{}') {
StoreUtil.init()
}
// 获取数据
return dataPreference?.getSync(key, 'default')
}
修改后,执行的日志如下:
09-19 12:01:13.792 19412-19412 A03D00/com.hw.example/JSAPP com.hw.example I result is test
问题分析
- 初始化未完成:您的代码中
StoreUtil.init()是异步操作(使用preferences.getPreferences的Promise版本),但在put和get方法中调用init()时没有使用await等待初始化完成。这可能导致在Preferences实例尚未初始化时就执行了存储或获取操作,从而获取到undefined。 - get方法未返回值:您的
StoreUtil.get()方法内部调用了dataPreference?.getSync(key, 'default'),但没有使用return语句返回结果。这导致方法返回一个解析为undefined的Promise,因此您在首页调用时得到undefined。 - 上下文(Context)可能不正确:您使用
const context = getContext(this) as common.UIAbilityContext获取context,但在全局或非UIAbility环境中,this可能无法正确指向UIAbilityContext。这会导致Preferences实例创建失败,存储和获取操作无效。 - 存储操作可能失败:您的
put方法使用了putSync和flushSync,但没有错误处理。如果存储过程中发生错误(如键名无效或存储失败),数据可能未被正确写入,导致获取时返回默认值或undefined。
解决方案
1. 确保初始化完成
- 修改
init方法,确保返回Promise,并在put和get中等待初始化完成。 - 使用单例模式,避免多次初始化。
2. 修正get方法返回值
- 在
get方法中返回getSync的结果,以便调用方可以获取到值。
3. 确保Context正确
- 在UIAbility中获取context并全局保存,或在StoreUtil中传递context参数。避免在全局作用域中使用
getContext(this),因为this可能未定义。
4. 添加错误处理
- 在存储和获取操作中添加异常捕获,打印错误日志以便调试。
修改后的代码示例
import { preferences } from "@kit.ArkData";
import { common } from '@kit.AbilityKit';
import { BusinessError } from "@kit.BasicServicesKit";
// 全局保存context,需在UIAbility中设置
let globalContext: common.UIAbilityContext | null = null;
// 设置全局context的函数(在UIAbility的onCreate中调用)
export function setGlobalContext(context: common.UIAbilityContext) {
globalContext = context;
}
let dataPreference: preferences.Preferences | null = null;
export class StoreUtil {
public static async init(): Promise<void> {
if (!globalContext) {
console.error("Context is not set. Please call setGlobalContext first.");
return;
}
try {
dataPreference = await preferences.getPreferences(globalContext, 'userStore');
console.info('Succeeded in getting preferences.');
} catch (e) {
console.error('Failed to get preferences. Error: ' + e);
}
}
public static async put(key: string, value: preferences.ValueType): Promise<void> {
if (!dataPreference) {
await StoreUtil.init();
}
if (!dataPreference) {
console.error("Preferences instance is null.");
return;
}
try {
dataPreference.putSync(key, value);
dataPreference.flushSync();
console.info("Succeeded in putting value.");
} catch (e) {
console.error("Failed to put value. Error: " + e);
}
}
public static async get(key: string, defaultValue: preferences.ValueType = 'default'): Promise<preferences.ValueType> {
if (!dataPreference) {
await StoreUtil.init();
}
if (!dataPreference) {
console.error("Preferences instance is null.");
return defaultValue;
}
try {
return dataPreference.getSync(key, defaultValue);
} catch (e) {
console.error("Failed to get value. Error: " + e);
return defaultValue;
}
}
public static async delete(key: string): Promise<void> {
if (!dataPreference) {
await StoreUtil.init();
}
if (!dataPreference) {
console.error("Preferences instance is null.");
return;
}
try {
dataPreference.deleteSync(key);
dataPreference.flushSync();
console.info("Succeeded in deleting value.");
} catch (e) {
console.error("Failed to delete value. Error: " + e);
}
}
}
在UIAbility中设置全局Context
在您的UIAbility(例如EntryAbility)中,设置全局context:
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { setGlobalContext } from '../utils/StoreUtil'; // 调整路径
class EntryAbility extends UIAbility {
onCreate() {
setGlobalContext(this.context);
// 可选:初始化StoreUtil
StoreUtil.init().then(() => {
console.info('StoreUtil initialized.');
});
}
}
在首页调用
在页面中,确保在操作前等待初始化完成,然后使用async/await或Promise方式调用:
// 存储数据
StoreUtil.put('userdata', '1231231').then(() => {
console.info('Storage successful.');
});
// 获取数据
StoreUtil.get('userdata').then((res) => {
console.info('Value from preferences: ' + res);
});
注意事项
- 同步与异步:您的代码混合了同步和异步方法。如果使用同步方法(如
getSync),请确保Preferences实例已初始化。建议统一使用异步方式以避免竞态条件。
分析
-
未正确初始化Preferences实例 必须确保
preferences.Preferences实例在使用前完成初始化,且每次操作前都通过getPreferences()获取同一实例 -
缺少数据持久化操作 存储数据后未调用
flush()方法,导致数据未真正写入磁盘 -
上下文(Context)不一致 如果通过不同
Context(如页面级Context与应用级Context)获取Preferences实例,会因沙箱隔离导致数据无法共享 -
生命周期未同步 在组件初始化阶段过早访问
Preferences可能导致状态变量未就绪
在HarmonyOS Next中,preferences获取到undefined通常是因为数据未正确存储或读取路径错误。请检查以下方面:
- 确保使用
preferences.getPreferences()时传入正确的context和name参数。 - 存储数据后是否成功调用了
flush()或flushSync()方法持久化。 - 读取时使用的key必须与存储时完全一致,注意大小写。
- 确认存储和读取操作在同一个preferences实例中进行。
检查代码逻辑,确保存储流程完整,无异步操作导致的时序问题。
在HarmonyOS Next中,preferences获取不到值(得到undefined)的主要原因是你的StoreUtil.get()方法没有正确返回Promise。从你的代码分析,问题出在以下几个方面:
核心问题分析
-
get()方法缺少返回值:public static async get(key:string){ // ... 代码省略 dataPreference?.getSync(key,'default') // 这里执行了但没有返回 } -
调用方式不正确:
// 错误的调用方式 let userdata = StoreUtil.get('userdata').then(res=>{...})
解决方案
1. 修改get()方法,添加返回值:
public static async get(key: string): Promise<preferences.ValueType> {
console.log(key)
// 检查dataPreference是否初始化
if (!dataPreference) {
console.log('未初始化,正在初始化...')
await StoreUtil.init()
}
try {
// 使用getSync同步获取值
const value = dataPreference?.getSync(key, 'default')
console.log(`获取到键值 ${key}: ${value}`)
return Promise.resolve(value)
} catch (error) {
console.error(`获取键值 ${key} 失败:`, error)
return Promise.resolve('default')
}
}
2. 修改初始化逻辑,确保异步完成:
public static async init(): Promise<void> {
try {
if (!dataPreference) {
dataPreference = await preferences.getPreferences(context, 'userStore')
console.info('success getPreferences')
}
} catch (e) {
console.error('初始化preferences失败:', e)
}
}
3. 正确的调用方式:
// 方式1:使用async/await
async function getUserData() {
try {
const userdata = await StoreUtil.get('userdata')
console.log('获取到的用户数据:', userdata)
} catch (error) {
console.error('获取数据失败:', error)
}
}
// 方式2:使用Promise.then
StoreUtil.get('userdata').then(res => {
console.log('获取到的用户数据:', res)
}).catch(error => {
console.error('获取数据失败:', error)
})
4. 修复put()方法中的初始化检查:
public static async put(key: string, value: string) {
// 正确的初始化检查
if (!dataPreference) {
console.log('preferences未初始化,正在初始化...')
await StoreUtil.init()
}
try {
dataPreference?.putSync(key, value)
await dataPreference?.flush()
console.log(`成功存储键值 ${key}: ${value}`)
} catch (e) {
console.error(`存储键值 ${key} 失败:`, e)
}
}
关键注意事项
- 异步初始化:确保在调用
get()或put()之前,init()方法已经完成执行 - 返回值类型:
get()方法需要明确返回Promise - 错误处理:添加适当的错误处理机制
- 同步/异步方法:注意
getSync是同步方法,但你的封装需要支持异步调用
按照上述修改后,你的preferences应该能正常获取到存储的值,而不是undefined。

