无法在 Flutter 上的 Main.dart 上正确使用 SharedPreferences?

问题描述 投票:0回答:1

我一直在学习 Flutter,并学习了这一点来改进 Pub.dev 包共享首选项的使用, 总而言之,它是创建一个我可以使用 SharedPreferences 在我的应用程序周围以更好的方式使用和工作的服务,它在我的代码

token
上完美运行,因为我有我的异步函数

因此, getMethod 使用

final token = await keyValueStorageService.getValue<String>('token')
(也是上面的异步函数)完美地工作, 但我无法在我的 UI 代码上使用此代码,它给了我这个(因为缺少等待函数)

但是正如我所读到的,您可以在 main.dart 上使用它并启动(如下所示),我一直在尝试使用

getSharedPrefs()
上的方法
main.dart
来在我的应用程序中实现和使用它,例如调用我的
getValue('user')
无论我需要但还没有成功

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Enviroment.initEnvirontment();
  //! Key Value instance for main async 
  await KeyValueStorageServiceImpl().getSharedPrefs();
  await initializeDateFormatting('es_ES', null);
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
      .then((value) => runApp(ProviderScope(child: MyApp())));
}

我的实际代码是这样的

键值存储.dart

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

class KeyValueStorageServiceImpl extends KeyValueStorageService {

  Future<SharedPreferences> getSharedPrefs() async {
    return await SharedPreferences.getInstance();
  }

  @override
  Future<T?> getValue<T>(String key) async {
    final prefs = await getSharedPrefs();
    switch (T) {
      case String:
        return prefs.getString(key) as T?;
      case int:
        return prefs.getInt(key) as T?;
      case double:
        return prefs.getDouble(key) as T?;
      case bool:
        return prefs.getBool(key) as T?;
      case List:
        return prefs.getStringList(key) as T?;
      default:
        throw UnimplementedError(
            'No implementation Get for ${T.runtimeType}');
    }
  }

  @override
  Future<bool> removeKey(String key) async {
    final prefs = await getSharedPrefs();
    return await prefs.remove(key);
  }

  @override
  Future<void> setKeyValue<T>(String key, T value) async {
    final prefs = await getSharedPrefs();

    switch (T) {
      case String:
        await prefs.setString(key, value as String);
        break;
      case int:
        await prefs.setInt(key, value as int);
        break;
      case double:
        await prefs.setDouble(key, value as double);
        break;
      case bool:
        await prefs.setBool(key, value as bool);
        break;
      case List:
        await prefs.setStringList(key, value as List<String>);
        break;
      default:
        throw UnimplementedError(
            'No implementation Set for  ${T.runtimeType}');
    }
  }
}

key_value_class.dart

abstract class KeyValueStorageService {
  Future<void> setKeyValue<T>(String key, T value);
  Future<T?> getValue<T>(String key);
  Future<bool> removeKey(String key);
}
flutter dart sharedpreferences flutter-sharedpreference
1个回答
0
投票

我做出改变的内容和原因:

  1. 直接将

    SharedPreferences
    的实例存储在
    KeyValueStorageServiceImpl
    类中,并使用构造函数进行初始化。这可以确保一旦
    main
    函数初始化
    SharedPreferences
    一次,随后就不需要在
    getInstance
    函数内再次调用
    getValue

  2. get
    SharedPreferences
    函数返回T?直接值而不是 Future 值,因此
    getValue
    函数不需要返回
    Future<T?>
    ,所以我更改了它的定义。

  3. 更改了

    key_value_class.dart

    中的函数签名
  4. 更改了 main 函数,将

    SharedPreferences
    对象传递给
    KeyValueStorageServiceImpl
    的构造函数。

  5. 通过将

    KeyValueStorageServiceImpl
    变成单例提供了另一种方法。

如果愿意,可以阅读我在代码中的注释。

key_value_storage.dart

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

class KeyValueStorageServiceImpl extends KeyValueStorageService {
  /// The instance of shared preferences is declared once for every object you create of this type.
  final SharedPreferences prefs;

  /// Call the `SharedPreferences.getInstance();` function outside of this class in order to not need to return a 
  /// future from the `getValue` method.
  KeyValueStorageServiceImpl(this.prefs);  

  /// The `get` operation returns the value itself, not a future.
  @override
  T? getValue<T>(String key) {
    switch (T) {
      case String:
        return prefs.getString(key) as T?;
      case int:
        return prefs.getInt(key) as T?;
      case double:
        return prefs.getDouble(key) as T?;
      case bool:
        return prefs.getBool(key) as T?;
      case List:
        return prefs.getStringList(key) as T?;
      default:
        throw UnimplementedError(
            'No implementation Get for ${T.runtimeType}');
    }
  }

  @override
  Future<bool> removeKey(String key) async {
    return await prefs.remove(key);
  }

  @override
  Future<void> setKeyValue<T>(String key, T value) async {
    switch (T) {
      case String:
        await prefs.setString(key, value as String);
        break;
      case int:
        await prefs.setInt(key, value as int);
        break;
      case double:
        await prefs.setDouble(key, value as double);
        break;
      case bool:
        await prefs.setBool(key, value as bool);
        break;
      case List:
        await prefs.setStringList(key, value as List<String>);
        break;
      default:
        throw UnimplementedError(
            'No implementation Set for  ${T.runtimeType}');
    }
  }
}

key_value_class.dart

abstract class KeyValueStorageService {
  Future<void> setKeyValue<T>(String key, T value);
  T? getValue<T>(String key);
  Future<bool> removeKey(String key);
}

main()
功能

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Enviroment.initEnvirontment();
  //! Key Value instance for main async 
  var prefs = await SharedPreferences.getInstance();
  // use this wherever you need to call `getValue`
  var keyValueStorageService = KeyValueStorageServiceImpl(prefs);
  await initializeDateFormatting('es_ES', null);
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
      .then((value) => runApp(ProviderScope(child: MyApp())));
}

使用单例的替代方法

key_value_storage.dart

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

class KeyValueStorageServiceImpl extends KeyValueStorageService {
  /// The instance of shared preferences
  final SharedPreferences prefs;

  /// The single instance which will remain all through the app lifecycle
  static KeyValueStorageServiceImpl? _instance;

  /// Getter for the instance
  static KeyValueStorageServiceImpl get instance => _instance!;

  /// Set the instance value, if not already set, by creating an object
  /// of `KeyValueStorageServiceImpl` type and passing the SharedPreferences.
  static void setSharedPreferences(SharedPreferences prefs) {
    _instance ??= KeyValueStorageServiceImpl._(prefs);
  }

  /// Private Constructor to prevent multiple instances of this class.
  KeyValueStorageServiceImpl._(this.prefs);  

  /// The `get` operation returns the value itself, not a future.
  @override
  T? getValue<T>(String key) {
    switch (T) {
      case String:
        return prefs.getString(key) as T?;
      case int:
        return prefs.getInt(key) as T?;
      case double:
        return prefs.getDouble(key) as T?;
      case bool:
        return prefs.getBool(key) as T?;
      case List:
        return prefs.getStringList(key) as T?;
      default:
        throw UnimplementedError(
            'No implementation Get for ${T.runtimeType}');
    }
  }

  @override
  Future<bool> removeKey(String key) async {
    return await prefs.remove(key);
  }

  @override
  Future<void> setKeyValue<T>(String key, T value) async {
    switch (T) {
      case String:
        await prefs.setString(key, value as String);
        break;
      case int:
        await prefs.setInt(key, value as int);
        break;
      case double:
        await prefs.setDouble(key, value as double);
        break;
      case bool:
        await prefs.setBool(key, value as bool);
        break;
      case List:
        await prefs.setStringList(key, value as List<String>);
        break;
      default:
        throw UnimplementedError(
            'No implementation Set for  ${T.runtimeType}');
    }
  }
}

main()
功能

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Enviroment.initEnvirontment();

  //! Key Value instance for main async 
  var prefs = await SharedPreferences.getInstance();
  KeyValueStorageServiceImpl.setSharedPreferences(prefs);
  
  await initializeDateFormatting('es_ES', null);
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
      .then((value) => runApp(ProviderScope(child: MyApp())));
}

现在无论您需要获取值,您都可以执行以下操作

var value = KeyValueStorageServiceImpl.instance.getValue<Type>('key');

希望这能解决您的问题!快乐编码! :)

© www.soinside.com 2019 - 2024. All rights reserved.