关于Flutter 使用GetStorage本地缓存的使用和需要注意的问题

使用

使用相对来说比较简单
存储:

GetStorage().write('your_key', your_value);

读取:

GetStorage().read('your_key');
问题

存储:
存储的时候 我们持久化的值 若是 系统的基础数据类型即 bool、String、int或是List、Map这些集合类型,且集合中也都是系统提供的数据类型,完全没有问题,
但是有时候 我们灰直接存储我们自定义的模型数据,比如

HomeTabItemModel(
    this.title,
    this.image,
  );
GetStorage().write('home_tab', itemModel);

这种也是可以直接存储的 但是 需要注意 itemModel 需要实现toJson() 方法,否则存储失败 或是 下次获取不到
原因是持久化时会调用json.encode()方法,该方法会调用非系统类的toJson()方法
这里需要注意 write()方法 写入分为两部分 一部分是内存中的数据(写入自定义模型,内存中就是我们自定义的模型);另一部分是磁盘中的数据,该数据是json序列化后的数据 与 自定义模型的toJson()对应,所以此时 我们磁盘和内存中的数据类型是不同的

///存储
Future<void> write(String key, dynamic value) async {
    // 内存
    writeInMemory(key, value);
    // final _encoded = json.encode(value);
    // await _concrete.write(key, json.decode(_encoded));
    // 磁盘
    return  _tryFlush();
  }
void writeInMemory(String key, dynamic value) {
    _concrete.write(key, value);
  }

内存

void write(String key, dynamic value) {
    subject
      ..value[key] = value
      ..changeValue(key, value);
    //return _writeToStorage(subject.value);
  }

磁盘

Future<void> _writeToStorage(Map<String, dynamic> data) async {
    localStorage.update(fileName, (val) => json.encode(subject.value),
        ifAbsent: () => json.encode(subject.value));
  }
/// If [toEncodable] is omitted, it defaults to a function that returns the
  /// result of calling `.toJson()` on the unencodable object.
  String encode(Object? value, {Object? toEncodable(dynamic object)?}) {
    toEncodable ??= _toEncodable;
    if (toEncodable == null) return encoder.convert(value);
    return JsonEncoder(toEncodable).convert(value);
  }

读取:

读取分类两种情况
1、系统类型的读取,这种不管什么时间读取 读取到的都是一样的都是我们存储的数据类型

GetStorage().read<bool>('your_key');
GetStorage().read<String>('your_key');
...

2、自定义类型存储后的读取
这种形式的读取分为两种情况
1》存储后 待下次冷启动才会调用read方法进行读取,这种读取到的是已经经过json序列化后的Map或是List数据,原因在存储的地方已经说明

Iterable? json = GetStorage().read('your_key');
    if (json != null) {
      List<ItemModel> list = List<ItemModel>.from(json.map((e) => ItemModel.fromJson(e)));
      if (list.isNotEmpty) {
        tabs(list);
      }
    }

2》存储后 还会在某个时刻读取,这种情况读取到的直接是我们自定的类型,此时读取到的是内存中经过存储更新后的数据,这种情况就会导致读取到的数据类型与磁盘中不同,最好读取方法这么写

void readFromCache() {
    Map<String, dynamic> map = Map.from(GetStorage().read("your_key") ?? {});
    List<ItemModel> models = [];
    for (var item in map.entries) {
      ItemModel itemModel;
      if (item.value is Map) {
        itemModel = ItemModel.fromJson(item.value);
      } else {
        itemModel = item.value;
      }
      models.add(itemModel);
    }
  }
总结

根据上述问题 建议在存储时尽量不使用我们自定义的数据类型直接存储,存储前要对数据进行序列化,存储系统提供的数据类型,这样可保证 内存和 磁盘中的数据一致,获取时不容易出错

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容