这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战
APP中的持久化数据存储是不可或缺的功能,本文主要介绍下Flutter中里面的几种持久化存储:
shared_preferences
安卓端,基于SharePreferences;iOS端基于NSUserDefaults开发 用于简单key-value形式存储
- 引入
dependencies:
shared_preferences: ^2.0.8
复制代码
- 基本用法:
class LocalStorage {
static SharedPreferences? prefs;
static initSP() async {
prefs = await SharedPreferences.getInstance();
}
static save(String key, String value) {
prefs?.setString(key, value);
}
static get(String key) {
return prefs?.get(key);
}
static remove(String key) {
prefs?.remove(key);
}
}
复制代码
path_provider
文件存储
- 引入
dependencies:
path_provider: ^2.0.7
复制代码
- 基本介绍
-
获取应用缓存目录: getTemporaryDirectory
- 类似iOS的NSTemporaryDirectory和Android的getCacheDir
- /data/user/0/包名/cache
-
获取应用文件目录: getApplicationDocumentsDirectory
- 类似iOS的NSDocumentDirectory和Android上的AppData目录
- 应用程序被删除时,系统会清除目录
- /data/user/0/包名/app_flutter
-
存储卡: getExternalStorageDirectory
- 仅支持Android平台
- /storage/emulated/0/Android/data/包名/files
- 基本用法
/// 拿到存储路径
Future<String> getTemporaryDirectoryString()async{
final directory = await getTemporaryDirectory();
return directory.path;
}
Future<String> getApplicationDocumentsDirectoryString()async{
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<String> getExternalStorageDirectoryString()async{
final directory = await getExternalStorageDirectory();
return directory?.path ?? "";
}
// 创建对文件位置的引用
Future<File> get _localFile async {
final path = await getApplicationDocumentsDirectoryString();
return new File('$path/counter.txt');
}
// 将数据写入文件
Future<File> writeCounter(int counter) async {
final file = await _localFile;
// Write the file
return file.writeAsString('$counter');
}
// 从文件中读取数据
Future<int> readCounter() async {
try {
final file = await _localFile;
// Read the file
String contents = await file.readAsString();
return int.parse(contents);
} catch (e) {
// If we encounter an error, return 0
return 0;
}
}
复制代码
sqflite数据库
- 引入
dependencies:
sqflite: ^2.0.0+4
复制代码
2.基本介绍
- 执行sq语句,创建表
- 提供获取Transaction的方法
- 使用Transaction执行增删改查的sq语句
- 基本使用
class MainDatabaseManager {
// 工厂模式
factory MainDatabaseManager() => _getInstance();
static MainDatabaseManager get instance => _getInstance();
static MainDatabaseManager? _instance;
static Database? tkDatabase;
static List<String> _nameList = [];
MainDatabaseManager._internal() {
// 初始化
}
static MainDatabaseManager _getInstance() {
if (_instance == null) {
_instance = new MainDatabaseManager._internal();
}
_instance!._createTable();
return _instance!;
}
///初始化数据库
initDB() {
_createTable();
}
///打开数据库,创建数据缓存表
_createTable() async {
var databasePath = await getDatabasesPath();
String path = join(databasePath, "tkDataBase.db");
///打开数据库
tkDatabase = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
/// 创建表
await db.execute(
"create table if not EXISTS TK_Main_Data (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,name TEXT UNIQUE,data BLOB)");
});
}
///操作事务Transaction
commitTransaction(Function(Transaction txn) action) async {
try {
await tkDatabase?.transaction((txn) async {
Batch batch = txn.batch();
await action(txn);
await batch.commit(noResult: true, continueOnError: true);
});
} catch (e) {
print('--- transaction failed -----');
}
}
/*
保存到数据库,区分当前用
- parameter name: 保存的名称(用于查询)
- parameter data: 数据
- parameter type: 类型
*/
_saveDataWith(
String name, bool containsMember, String data, Transaction txn) async {
String dataName = name + (containsMember ? UserStore().getMemberId() : "");
int id = await txn.rawInsert(
'INSERT or replace INTO TK_Main_Data(name,data) VALUES(?,?)',
[dataName, data]);
print('inserted2:$id');
}
///更新数据
updateData(
String name, bool containsMember, dynamic data, Transaction txn) async {
dynamic result = await selectData(name, containsMember, txn);
if (result == null || result == "") {
_nameList.add(name);
}
_saveDataWith(name, containsMember, data, txn);
}
/*
查询数据
- parameter name: 要查询的数据的名称
- parameter type: 类型
- returns: 返回的数据
*/
Future<dynamic> selectData(
String name, bool containsMember, Transaction txn) async {
String dataName = name + (containsMember ? UserStore().getMemberId() : "");
/// 查询
dynamic result = await txn
.rawQuery("select data from TK_Main_Data where name = '$dataName'");
if (result != null && result is List && result.length > 0) {
return result.first["data"] ?? "";
}
return "";
}
///退出登录时,删除与当前用户有关的缓存
deleteAllDataForMember(Transaction txn) async {
if (UserStore.instance.getMemberId() != "") {
for (String name in _nameList) {
String dataName =
name + UserStore.instance.getMemberId(); //与当前用户有关的,无关的不需要删除
await txn
.execute("delete from TK_Main_Data where name = (?)", [dataName]);
}
_nameList = [];
}
}
onDisposed() {
tkDatabase?.close();
}
}
复制代码