flutter - Flutter:共享首选项单例未正确初始化
问题描述
我对 Flutter 和 Dart 很陌生,来自 android,带着我的一些习惯,我想实现一个 SharedPreferences 单例对象来简化和避免重复(重复)。这是我的 SharedPreferences 单例类:
import 'package:shared_preferences/shared_preferences.dart';
import 'package:synchronized/synchronized.dart';
class MySharedPreferences {
static MySharedPreferences _instance;
SharedPreferences _preferences;
// keys
final String _logged = "LOGGED";
final String _accessToken = "ACCESS_TOKEN";
MySharedPreferences._() {
_initSharedPreferences();
}
static MySharedPreferences getInstance() {
var lock = new Lock();
if (_instance == null) {
lock.synchronized(() => {_instance = new MySharedPreferences._()});
return _instance;
} else
return _instance;
}
_initSharedPreferences() async {
_preferences = await SharedPreferences.getInstance();
}
bool checkLogged() {
return _preferences.getBool(_logged);
}
void setLogged(bool logged) {
_preferences.setBool(_logged, logged);
}
好吧,大部分逻辑都是我以前在 android 中做的,并且曾经完美地工作,但是当我尝试对其进行测试时,单例始终为空,这是测试:
import 'package:flutter_test/flutter_test.dart';
import 'package:reportingsystem/local/my_shared_preferences.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('Test the shared_preferences', () {
MySharedPreferences preferences = MySharedPreferences.getInstance();
preferences.setLogged(true);
expect(preferences.checkLogged(), true);
preferences.setLogged(false);
expect(preferences.checkLogged(), false);
});
}
测试失败,因为“首选项”对象为空,我不知道出了什么问题,而且我在文档中找不到太多关于它的信息。这是堆栈跟踪:
dart:core Object.noSuchMethod
package:reportingsystem/local/my_shared_preferences.dart 34:18 MySharedPreferences.setLogged
test\shared_preferences_test.dart 8:17 main.<fn>
test\shared_preferences_test.dart 6:39 main.<fn>
NoSuchMethodError: The method 'setBool' was called on null.
Receiver: null
Tried calling: setBool("LOGGED", true)
解决方案
这是一个示例,您必须init
在第一次调用 Singleton 时调用它,然后才能同步访问它。
class MySharedPreferences {
static final MySharedPreferences _instance = MySharedPreferences._internal();
MockSharedPreferences prefereces;
factory MySharedPreferences() {
return _instance;
}
Future<void> init() async {
if (prefereces != null) {
return;
}
prefereces = await Future.delayed(Duration(seconds: 1), () => MockSharedPreferences());
}
MySharedPreferences._internal();
}
class MockSharedPreferences {
final Map<String, bool> data = {};
void setBool(String key, bool value) {
data[key] = value;
print('data $data');
}
}
然后你可以await
在第一次初始化后使用它,如下所示:
Future<void> main() async {
await first();
anyOther();
}
void anyOther() {
MySharedPreferences singleton = MySharedPreferences();
singleton.prefereces.setBool('first', true);
}
Future<void> first() async {
MySharedPreferences singleton = MySharedPreferences();
await singleton.init();
singleton.prefereces.setBool('notFirst', true);
}
推荐阅读
- ios - iOS 奇数线程 1:致命错误:iPad 上的索引超出范围
- javascript - 如何查询溢出隐藏区域中的元素:滚动
- java - 如何提高嵌入在 pdf 中的签名图像的质量
- javascript - 仅使用 Array.prototype.map() 和 Array.prototype.filter() 来实现以下结果
- autodesk-forge - AutoDesk Forge 上的 DWG 图纸组合失败
- anaconda - 在 IBM Power 9 机器上使用 conda 安装 MKL
- javascript - 为什么 Position:Top of my table 不基于文档对象?
- django - 提交带有多个不同按钮的表单
- amazon-web-services - 发生无服务器首次部署错误:HelloLogGroup - 用户
- javascript - 使用js的倒数计时器