美文网首页
关于Flutter 使用GetStorage本地缓存的使用和需要

关于Flutter 使用GetStorage本地缓存的使用和需要

作者: 黑炭长 | 来源:发表于2024-09-24 15:13 被阅读0次
    使用

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

    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);
        }
      }
    
    总结

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

    相关文章

      网友评论

          本文标题:关于Flutter 使用GetStorage本地缓存的使用和需要

          本文链接:https://www.haomeiwen.com/subject/mgdqrjtx.html