如何在Flutter中创建SharedPreferences的单例类

11

总是需要 SharedPreferences 的对象,但我们使用 await 来访问它,如下所示:

await SharedPreferences.getInstance();

这就是为什么我想创建 SharedPreferences 的单例类,并创建 GET 和 SET 数据到 SharedPreferences 的静态方法。

但我不知道该如何做到这一点,我尝试了,但没有成功。请帮帮我。

5个回答

21

要处理单例类 SharedPreference,请按照以下3个步骤进行操作:

1. 将此类放入您的项目中

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

    class PreferenceUtils {
      static Future<SharedPreferences> get _instance async => _prefsInstance ??= await SharedPreferences.getInstance();
      static SharedPreferences _prefsInstance;

      // call this method from iniState() function of mainApp().
      static Future<SharedPreferences> init() async {
        _prefsInstance = await _instance;
        return _prefsInstance;
      }

      static String getString(String key, [String defValue]) {
        return _prefsInstance.getString(key) ?? defValue ?? "";
      }

      static Future<bool> setString(String key, String value) async {
        var prefs = await _instance;
        return prefs?.setString(key, value) ?? Future.value(false);
      }
    }


2. 在主类的initState()中初始化此类

PreferenceUtils.init();

3. 访问您的方法:

PreferenceUtils.setString(AppConstants.USER_NAME, "");
String username = PreferenceUtils.getString(AppConstants.USER_NAME);

1
伟大的答案!我发现一个问题:static SharedPreferences _prefs; 应该被移除,_instance应该使用_prefsInstance。而不是_prefs。 - ruclip
5
未处理的异常:NoSuchMethodError:在null上调用了“getString”方法。 E/flutter(11362):接收器:null E/flutter(11362):尝试调用:getString(“token”)_prefsInstance为null。 - Radhey
1
空安全抛出未处理的异常:LateInitializationError: Field '_prefsInstance@1023372235' 未被初始化。由于静态延迟的SharedPreferences _prefsInstance; 有什么解决方案吗? - Ravi Parmar
@rmalviya 的回答是当前 Flutter 版本中更好的答案。 - CrashOverride

18

你可以使用以下非常简单的类来获取SharedPreferences实例而不需要await

import 'package:shared_preferences/shared_preferences.dart';

class SharedPrefs {
  static late final SharedPreferences instance;

  static Future<SharedPreferences> init() async =>
      instance = await SharedPreferences.getInstance();
}
  1. main()函数中初始化instance,如下所示:
void main() async {
  // Required for async calls in `main`
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize SharedPrefs instance.
  await SharedPrefs.init();

  runApp(MyApp());
}
  1. 访问 SharedPrefs.instance 上的方法,例如:
final someString = SharedPrefs.instance.getString('someString') ?? 'defaultValue';
await SharedPrefs.instance.setBool('someBool', true);
额外信息:
如果希望,可以通过重新定义这些方法(getBoolsetString等)或在SharedPrefs类本身中定义新方法(getUsersetUsersetAccessToken等),并将instance作为私有字段(如_instance)。其中一个示例如下:
// Getter
static bool? getBool(String key) => _instance.getBool(key);

// Setter
static Future<bool> setBool(String key, bool value) => _instance.setBool(key, value);

// More abstraction
static const _kAccessToken = 'accessToken';

static Future<bool> setAccessToken(String value) => _instance.setString(_kAccessToken, value);

static String? getAccessToken() => _instance.getString(_kAccessToken);

接下来,您只需按照以下方式调用这些方法即可:

final someBool = SharedPrefs.getBool('someBool') ?? false;
await SharedPrefs.setBool('someBool', someBool);

final accessToken = SharedPrefs.getAccessToken();

1
这是现在更好的答案!谢谢 - CrashOverride

2

这是我关于首选项的解决方案:

class Storage {
  static const String _some_field = 'some_field';

  static Future<SharedPreferences> get prefs => SharedPreferences.getInstance();

  static Future<String> getSomeStringData() async =>
      (await prefs).getString(_some_field) ?? '';

  static Future setSomeStringData(String phone) async =>
      (await prefs).setString(_some_field, phone);

  static Future clear() async {
    await getSomeStringData(null);
  }
}

0

我使用这段代码来实现单例模式的偏好设置

static Future<SharedPreferences>  getInstance() async
  {
    SharedPreferences preferences ;
    preferences = await SharedPreferences.getInstance();
    return preferences;
  }

然后像这样使用它来恢复您的数据,此处我恢复了userId。

 /// ----------------------------------------------------------
  /// Method that saves/restores the userId
  /// ----------------------------------------------------------
   static Future<String>  getUserId() async {
    return getInstance().then((pref) {
      return pref.get(Constants.userId);
    });
  }

希望能有所帮助 :)

-1
class YourClass {
    static final YourClass _singleton = 
           new YourClass._internal();

    factory YourClass(){
            return _singleton;
    }
    
    YourClass._internal(){
            //initialization your logic here
    }

}

//main code env
//get back the singleton to you
YourClass mClass = new YourClass(); 

问题是关于SharedPreferences在单例中的使用,而不是一般的单例类。 - IvanMih
请仔细阅读问题... - Abed Putra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接