我正在使用riverpod
和flutter_hooks
我正在尝试使用这两种方法来实现shared_prefrences
,这就是我目前所做的:
pref_changenotifier.dart
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
const _isloggedkey = 'logged';
const _boardingkey = "boarding";
const _apiTokenkey = 'apitoken';
const _rolekey = 'role';
class PrefChangeNotifier with ChangeNotifier {
late final SharedPreferences _sharedPreferences;
PrefChangeNotifier(this._sharedPreferences) {
getPref();
notifyListeners();
}
bool? _islogged;
bool? _boarding;
String? _apitoken;
String? _role;
String get apitoken => _apitoken!;
String get role => _role!;
bool get islogged => _islogged!;
bool get boarding => _boarding!;
void getPref() async {
_islogged = _sharedPreferences.getBool(_isloggedkey);
_apitoken = _sharedPreferences.getString(_apiTokenkey);
_boarding = _sharedPreferences.getBool(_boardingkey);
notifyListeners();
}
void setLoggedValue(bool logged) async {
await _sharedPreferences.setBool(_isloggedkey, logged);
_islogged = logged;
notifyListeners();
}
void setTokenValue(String apitoken) async {
await _sharedPreferences.setString(_apiTokenkey, apitoken);
_apitoken = apitoken;
notifyListeners();
}
void setBoardingValue(bool boarding) async {
await _sharedPreferences.setBool(_boardingkey, boarding);
_boarding = boarding;
notifyListeners();
}
void setRoleValue(String role) async {
await _sharedPreferences.setString(_rolekey, role);
_role = role;
notifyListeners();
}
void clearAllValues() async {
await _sharedPreferences.clear();
notifyListeners();
}
}
pref_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'pref_changenotifier.dart';
import 'package:shared_preferences/shared_preferences.dart';
final sharedPreferences = FutureProvider<SharedPreferences>(
(ref) async => await SharedPreferences.getInstance());
final prefChangeNotifierProvider =
ChangeNotifierProvider<PrefChangeNotifier>((ref) {
final sharePreferencesData = ref.watch(sharedPreferences).asData;
late final SharedPreferences prefs;
if (sharePreferencesData != null) {
prefs = sharePreferencesData.value;
}
return PrefChangeNotifier(prefs);
});
但每当我用ref.read(prefChangeNotifierProvider).setBoardingValue(true);
调用它时,它就会抛出这个错误
E/flutter (22947): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: An exception was thrown while building ChangeNotifierProvider<PrefChangeNotifier>#05878.
E/flutter (22947):
E/flutter (22947): Thrown exception:
E/flutter (22947): An exception was thrown while building _NotifierProvider<PrefChangeNotifier>#3bb8a.
E/flutter (22947):
E/flutter (22947): Thrown exception:
E/flutter (22947): LateInitializationError: Local 'prefs' has not been initialized.
E/flutter (22947):
E/flutter (22947): Stack trace:
我知道问题出在初始化延迟,但我该怎么办?
是的,这不是很明显吗?您使用late final SharedPreferences prefs
,然后使用prefs = sharePreferencesData.value
。您尚未启动该变量,因此无法对其执行任何操作。您可以在async函数中将其更改为:final SharedPreferences prefs = await SharedPreferences.getInstance()
。
关于代码的另一个问题是,当您调用getBool((、getString((,它可能为null(如果您没有在共享偏好中保存任何内容(。你可以使用这样的东西:
isLogin = prefs.getBool(SHARED_PREFS_KEY_LOGIN) ?? false;
将此方法放入PrefChangeNotifier类
static Future initMySharedPreferences() async {
_sharedPreferences = await SharedPreferences.getInstance();
}
并在main.dart 中初始化
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await PrefChangeNotifier.initMySharedPreferences();
runApp(MyApp());
}