在 HarmonyOS 中使用 ArkTS Preferences 构建持久暗模式

发布: (2026年2月20日 GMT+8 14:32)
4 分钟阅读
原文: Dev.to

I’m happy to translate the article for you, but I don’t have access to the full text of the linked page. Could you please paste the article’s content here (or the portions you’d like translated)? Once I have the text, I’ll provide a faithful Simplified‑Chinese translation while preserving the original formatting, markdown, and code blocks.

Problem Description

Many HarmonyOS applications need to store small amounts of data locally—for example, user preferences, recently viewed items, or simple state flags.

Developers often rely on in‑memory variables, but those values disappear when the app restarts.

We need a persistent and lightweight way to save and retrieve key‑value pairs.

背景知识

HarmonyOS 提供 @kit.ArkData(新包名)模块,其中包含用于简单键值存储的 preferences API。

  • 数据以键值对(stringnumberboolean 等)的形式存储在设备上的一个 preferences 文件中。
  • 可以使用同步或异步方法访问这些值。
  • flush() 确保更改被实际写入磁盘。

故障排除流程

使用 preferences 时的常见陷阱:

陷阱为什么重要
put() 后未调用或等待 flush()如果在缓冲区写入之前应用被杀死,修改可能会丢失。
在初始化之前尝试读取键必须先调用 getPreferencesSyncgetPreferences
忘记处理错误在回调中始终检查 BusinessError

分析结论

使用 preferences API 并进行适当的初始化以及显式调用 flush(),可以确保用户设置(例如暗色模式)在应用启动之间保持持久。这种方法轻量且避免了写入存储时的竞争条件。

解决方案

下面是一份 单个 .ets 文件,实现了使用 @kit.ArkData 偏好设置的持久化 暗黑模式切换。它会存储 darkMode 布尔值,实时更新 UI,并在应用重启后记住该设置。

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

class PreferencesUtil {
  private static instance: PreferencesUtil | null = null;
  private dataPreferences: preferences.Preferences | null = null;
  private readonly PREFERENCES_NAME = 'userSettings';
  private readonly DARK_MODE_KEY = 'IsDarkMode';

  private constructor() {}

  static getInstance(): PreferencesUtil {
    if (!PreferencesUtil.instance) {
      PreferencesUtil.instance = new PreferencesUtil();
    }
    return PreferencesUtil.instance;
  }

  async initPreferences(context: common.UIAbilityContext): Promise {
    const options: preferences.Options = { name: this.PREFERENCES_NAME };
    this.dataPreferences = preferences.getPreferencesSync(context, options);
    console.info('Preferences initialized');
  }

  getDarkModePreference(): boolean {
    if (!this.dataPreferences) return false;
    try {
      return this.dataPreferences.getSync(this.DARK_MODE_KEY, false) as boolean;
    } catch (err) {
      console.error('Failed to read preference:', err);
      return false;
    }
  }

  saveDarkModePreference(isDarkMode: boolean, callback?: () => void): void {
    if (!this.dataPreferences) return;
    try {
      this.dataPreferences.putSync(this.DARK_MODE_KEY, isDarkMode);
      this.dataPreferences.flush((err: BusinessError) => {
        if (err) {
          console.error(`Flush failed: ${err.code} - ${err.message}`);
        } else {
          console.info('DarkMode saved:', isDarkMode);
          callback?.();
        }
      });
    } catch (err) {
      console.error('Failed to save preference:', err);
    }
  }

  toggleDarkMode(callback?: (newState: boolean) => void): void {
    const newState = !this.getDarkModePreference();
    this.saveDarkModePreference(newState, () => callback?.(newState));
  }
}

@Entry
@Component
struct DarkModePage {
  @State isDarkMode: boolean = false;
  private preferencesUtil: PreferencesUtil = PreferencesUtil.getInstance();

  async aboutToAppear() {
    const ctx = this.getUIContext().getHostContext() as common.UIAbilityContext;
    await this.preferencesUtil.initPreferences(ctx);
    this.isDarkMode = this.preferencesUtil.getDarkModePreference();
  }

  private toggleTheme() {
    this.preferencesUtil.toggleDarkMode((newState: boolean) => {
      this.isDarkMode = newState;
    });
  }

  build() {
    Column() {
      Text(`Dark Mode is ${this.isDarkMode ? 'ON' : 'OFF'}`)
        .fontSize(20)
        .margin({ bottom: 20 })
        .fontColor(this.isDarkMode ? '#FFFFFF' : '#000000');

      Button(this.isDarkMode ? 'Turn OFF' : 'Turn ON')
        .fontSize(18)
        .fontColor(this.isDarkMode ? '#000000' : '#FFFFFF')
        .backgroundColor(this.isDarkMode ? '#BBBBBB' : '#333333')
        .borderRadius(20)
        .padding({ left: 16, right: 16, top: 10, bottom: 10 })
        .onClick(() => this.toggleTheme());
    }
    .width('100%')
    .height('100%')
    .backgroundColor(this.isDarkMode ? '#000000' : '#FFFFFF')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center);
  }
}

验证结果

  1. 启动应用并点击 Turn ON → 背景变为黑色,文字变为白色。
  2. 关闭并重新启动应用 → 暗色模式 状态被记住。

Verification Screenshot

![3.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y8m9dxhab3ukqlpz8obg.png)

[![3.png](https://media2.dev.to/dynamic/image/width=800,height=,fit=scale-down,gravity=auto,format=auto/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnokpbpeldslax9ohrgb.png)](https://media2.dev.to/dynamic/image/width=800,height=,fit=scale-down,gravity=auto,format=auto/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnokpbpeldslax9ohrgb.png)

---

### Related Documents or Links

- 

---

*Written by Hatice Akyel*
0 浏览
Back to Blog

相关文章

阅读更多 »

LIVO 下一代 Flutter 状态管理

Flutter 很棒,但状态管理很快就会变得混乱。你可能在小项目中使用过 setState,或者在更大的应用中使用 Provider、Riverpod 或 BLoC——b...