APP中的耐久化数据存储是不可或缺的功能,本文主要介绍下Flutter中里面的几种耐久化存储:

shared_preferences

安卓端,根据SharePreferences;iOS端根据NSUserDefaults开发
用于简单key-value方式存储

  1. 引入
dependencies:
  shared_preferences: ^2.0.8
  1. 根本用法:

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

文件存储

  1. 引入
dependencies:
    path_provider: ^2.0.7
  1. 根本介绍
  • 获取应用缓存目录: 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
  1. 根本用法
/// 拿到存储途径
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数据库

  1. 引入
dependencies:
  sqflite: ^2.0.0+4

2.根本介绍

  • 履行sq句子,创建表
  • 供给获取Transaction的方法
  • 运用Transaction履行增修改查的sq句子
  1. 根本运用

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();
  }
}