You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带初始化逻辑的Dart单例类?以SharedPreference服务为例

Dart SharedPreference 单例封装实现

实现说明

需要同时满足两个要求:

  • 类全局唯一实例(单例)
  • 确保_prefs实例初始化完成后才会被方法调用,避免LateInitializationError

方案1:启动预初始化(推荐,性能更优)

提前在应用启动阶段完成初始化,后续调用无异步等待开销。

封装代码

import 'package:shared_preferences/shared_preferences.dart';

class SharedPreferenceService {
  // 静态单例实例
  static late final SharedPreferenceService _instance;
  // 初始化完成的SharedPreferences实例
  late final SharedPreferences _prefs;

  // 私有构造函数,禁止外部手动实例化
  SharedPreferenceService._();

  /// 初始化方法,必须在main函数runApp前调用
  static Future<SharedPreferenceService> init() async {
    _instance = SharedPreferenceService._();
    _instance._prefs = await SharedPreferences.getInstance();
    return _instance;
  }

  /// 对外获取单例的入口
  static SharedPreferenceService get instance => _instance;

  // 原有业务方法
  Future<void> setIntroPagesHaveBeenViewed() async {
    await _prefs.setBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
  }

  Future<bool> checkIfIntroPagesHaveBeenViewed() async {
    return _prefs.getBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
  }
}

使用方式

在项目入口main函数中提前初始化:

void main() async {
  // 确保Flutter框架绑定已初始化
  WidgetsFlutterBinding.ensureInitialized();
  // 等待SharedPreference单例初始化完成
  await SharedPreferenceService.init();
  runApp(const MyApp());
}

业务代码中直接调用:

// 存储状态
await SharedPreferenceService.instance.setIntroPagesHaveBeenViewed();
// 读取状态
bool hasViewed = await SharedPreferenceService.instance.checkIfIntroPagesHaveBeenViewed();

方案2:懒加载初始化

无需提前初始化,第一次使用时自动完成初始化,适合对启动速度要求极高的场景。

封装代码

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:async';

class SharedPreferenceService {
  // 静态单例实例
  static final SharedPreferenceService _instance = SharedPreferenceService._internal();
  // 用于等待SharedPreferences初始化完成的Completer
  final Completer<SharedPreferences> _prefsCompleter = Completer<SharedPreferences>();

  // 工厂构造函数,对外返回唯一实例
  factory SharedPreferenceService() {
    return _instance;
  }

  // 内部私有构造
  SharedPreferenceService._internal() {
    _initPrefs();
  }

  // 异步初始化SharedPreferences
  void _initPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    _prefsCompleter.complete(prefs);
  }

  // 原有业务方法,内部自动等待初始化完成
  Future<void> setIntroPagesHaveBeenViewed() async {
    final prefs = await _prefsCompleter.future;
    await prefs.setBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
  }

  Future<bool> checkIfIntroPagesHaveBeenViewed() async {
    final prefs = await _prefsCompleter.future;
    return prefs.getBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
  }
}

使用方式

无需提前初始化,业务代码直接调用即可:

// 存储状态
await SharedPreferenceService().setIntroPagesHaveBeenViewed();
// 读取状态
bool hasViewed = await SharedPreferenceService().checkIfIntroPagesHaveBeenViewed();

内容的提问来源于stack exchange,提问作者Agung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 17:15:03