1. 引入依赖
# https://github.com/tekartik/synchronized.dart
synchronized: '>=3.0.0 <4.0.0'
# https://github.com/flutter/plugins/tree/master/packages/shared_preferences
shared_preferences: '>=2.0.3 <4.0.0'
2. SpUtil
library sp_util;
import 'dart:async';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:synchronized/synchronized.dart';
/**
* @Author: Sky24n
* @GitHub: https://github.com/Sky24n
* @Email: sky24no@gmail.com
* @Date: 2018/9/8
* @Description: Sp Util.
*/
/// SharedPreferences Util.
class SpUtil {
static SpUtil? _singleton;
static SharedPreferences? _prefs;
static Lock _lock = Lock();
static Future<SpUtil?> getInstance() async {
if (_singleton == null) {
await _lock.synchronized(() async {
if (_singleton == null) {
// keep local instance till it is fully initialized.
// 保持本地实例直到完全初始化。
var singleton = SpUtil._();
await singleton._init();
_singleton = singleton;
}
});
}
return _singleton;
}
SpUtil._();
Future _init() async {
_prefs = await SharedPreferences.getInstance();
}
/// put object.
static Future<bool>? putObject(String key, Object value) {
return _prefs?.setString(key, json.encode(value));
}
/// get obj.
static T? getObj<T>(String key, T f(Map v), {T? defValue}) {
Map? map = getObject(key);
return map == null ? defValue : f(map);
}
/// get object.
static Map? getObject(String key) {
String? _data = _prefs?.getString(key);
return (_data == null || _data.isEmpty) ? null : json.decode(_data);
}
/// put object list.
static Future<bool>? putObjectList(String key, List<Object> list) {
List<String>? _dataList = list.map((value) {
return json.encode(value);
}).toList();
return _prefs?.setStringList(key, _dataList);
}
/// get obj list.
static List<T>? getObjList<T>(String key, T f(Map v),
{List<T>? defValue = const []}) {
List<Map>? dataList = getObjectList(key);
List<T>? list = dataList?.map((value) {
return f(value);
}).toList();
return list ?? defValue;
}
/// get object list.
static List<Map>? getObjectList(String key) {
List<String>? dataLis = _prefs?.getStringList(key);
return dataLis?.map((value) {
Map _dataMap = json.decode(value);
return _dataMap;
}).toList();
}
/// get string.
static String? getString(String key, {String? defValue = ''}) {
return _prefs?.getString(key) ?? defValue;
}
/// put string.
static Future<bool>? putString(String key, String value) {
return _prefs?.setString(key, value);
}
/// get bool.
static bool? getBool(String key, {bool? defValue = false}) {
return _prefs?.getBool(key) ?? defValue;
}
/// put bool.
static Future<bool>? putBool(String key, bool value) {
return _prefs?.setBool(key, value);
}
/// get int.
static int? getInt(String key, {int? defValue = 0}) {
return _prefs?.getInt(key) ?? defValue;
}
/// put int.
static Future<bool>? putInt(String key, int value) {
return _prefs?.setInt(key, value);
}
/// get double.
static double? getDouble(String key, {double? defValue = 0.0}) {
return _prefs?.getDouble(key) ?? defValue;
}
/// put double.
static Future<bool>? putDouble(String key, double value) {
return _prefs?.setDouble(key, value);
}
/// get string list.
static List<String>? getStringList(String key,
{List<String>? defValue = const []}) {
return _prefs?.getStringList(key) ?? defValue;
}
/// put string list.
static Future<bool>? putStringList(String key, List<String> value) {
return _prefs?.setStringList(key, value);
}
/// get dynamic.
static dynamic getDynamic(String key, {Object? defValue}) {
return _prefs?.get(key) ?? defValue;
}
/// have key.
static bool? haveKey(String key) {
return _prefs?.getKeys().contains(key);
}
/// contains Key.
static bool? containsKey(String key) {
return _prefs?.containsKey(key);
}
/// get keys.
static Set<String>? getKeys() {
return _prefs?.getKeys();
}
/// remove.
static Future<bool>? remove(String key) {
return _prefs?.remove(key);
}
/// clear.
static Future<bool>? clear() {
return _prefs?.clear();
}
/// Fetches the latest values from the host platform.
static Future<void>? reload() {
return _prefs?.reload();
}
///Sp is initialized.
static bool isInitialized() {
return _prefs != null;
}
/// get Sp.
static SharedPreferences? getSp() {
return _prefs;
}
}
3. 初始化
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SpUtil.getInstance();
runApp(_widgetForRoute(window.defaultRouteName));
}
初始化后就可以直接使用了。
4. 注意事项
- Flutter的sp生成的文件在data/data/包名/shared_prefs/文件夹下面
如果混合开发,原生端和Flutter
端调用是有些区别的,如上所示,是flutter
端调用如下代码生成的FlutterSharedPreferences.xml
SpUtil.putString("result", "test");
flutter不需要我们指定文件名,而且生成后,name
自动添加flutter.
,上述key在sp文件中变成了flutter.result
。而Flutter
获取result
对应的值如下所示:
String? sp = SpUtil.getString("result");
如果原生端要获取flutter
创建的sp
,则需要如下方式:
SharedPreferences sp = context.getSharedPreferences("FlutterSharedPreferences",
Context.MODE_PRIVATE);
String value = sp.getString("flutter.result", "");
- 混合开发时可能报错:
E/flutter (28814): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
解决方案:在Android原生端的FlutterActivity或者FlutterFragment里面添加如下代码
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
GeneratedPluginRegistrant.registerWith(flutterEngine);
}