美文网首页
flutter 中 Json 泛型类数据处理

flutter 中 Json 泛型类数据处理

作者: 简单coder | 来源:发表于2022-01-03 19:45 被阅读0次

如果你目前正在使用 flutter 作为你的开发语言,那么你一定会碰到我取的这个标题所述的问题.

问题

为什么呢,因为 flutter 不支持反射,甚至禁用引入dart反射的这个库,所以我们需要生成具体的类的 fromJson 方法,对每一个字段进行decode 解析取值.



也是因为反射,你在编写通用解析类的时候,无法动态生成类,无法获取类的属性,方法等等,无法生成类似 iOS 那种,硬编码调用方法的实现
举个例子原生端与flutter 端交互通信的问题

iOS 中,我们可以硬编码 call.method 的方法字符串,生成方法调用,从而省去字符串等式判断.

flutter 通知原生 原生接收到 flutter 调用,直接调用

而在 dart 中,我们只能添加字符串等于判断来调用其方法,相当于在 MethodCallHandler中要一一注册dart 中调用的方法,过程就多了一步.

正文

然后回到本文来,你可能用到过FlutterJsonBeanFactory,这是 Android Studio 的一个插件,用于生成 json to model 的文件


他会主动帮你生成 fromJson 和 toJson 方法,并且用泛型类去解析,具体为
// 传入一个泛型,判断数组还是json 对象,进行具体的类判断解析
static M? fromJsonAsT<M>(dynamic json) {
    if (json == null) {
      return null;
    }
    if (json is List) {
      return _getListChildType<M>(json);
    } else {
      return _fromJsonSingle<M>(json as Map<String, dynamic>);
    }
  }
static M? _fromJsonSingle<M>(Map<String, dynamic> json) {
    final String type = M.toString();
    if (type == (ListModel).toString()) {
      return ListModel.fromJson(json) as M;
    }
    if (type == (Post).toString()) {
      return Post.fromJson(json) as M;
    }
    if (type == (GiftList).toString()) {
      return GiftList.fromJson(json) as M;
    }
    if (type == (Location).toString()) {
      return Location.fromJson(json) as M;
    }
    if (type == (NewGiftBag).toString()) {
      return NewGiftBag.fromJson(json) as M;
    }
    if (type == (PropList).toString()) {
      return PropList.fromJson(json) as M;
    }
    if (type == (Stat).toString()) {
      return Stat.fromJson(json) as M;
    }
    if (type == (TreasureResource).toString()) {
      return TreasureResource.fromJson(json) as M;
    }
    if (type == (UserEntity).toString()) {
      return UserEntity.fromJson(json) as M;
    }
    if (type == (APIResponse).toString()) {
      return APIResponse.fromJson(json) as M;
    }

    print("$type not found");

    return null;
  }

更详细的我就不贴了,如果你使用了之后,你就会发现,他有一个问题,你不能继续传入泛型类的类型,
比如我这里最后要讲解的 Model类型

class ListModel<T> {
  bool? hasMore;
  int? pageSize;
  int? pageNumber;
  bool? empty;
  int? total;
  int? totalPage;
  List<T>? list;
}

这种 model 是我的业务需要,相当于每个列表的返回数据类型都是这种类型,我即需要 List<T>数据,又需要 hasMore 这种后端返回帮我判断是否能进行上拉加载的字段,所以我必须要一个泛型类去解析.

接下来就是具体的代码实现

// 告诉 jsonConvert不解析该字段
@JSONField(name: "list", deserialize: false)
  List<T>? list;
factory ListModel.fromJson(Map<String, dynamic> json) {
    final ListModel<T> listModel = ListModel<T>();
    final bool? hasMore = jsonConvert.convert<bool>(json['hasMore']);
    if (hasMore != null) {
      listModel.hasMore = hasMore;
    }
    final int? pageSize = jsonConvert.convert<int>(json['pageSize']);
    if (pageSize != null) {
      listModel.pageSize = pageSize;
    }
    final int? pageNumber = jsonConvert.convert<int>(json['pageNumber']);
    if (pageNumber != null) {
      listModel.pageNumber = pageNumber;
    }
    final bool? empty = jsonConvert.convert<bool>(json['empty']);
    if (empty != null) {
      listModel.empty = empty;
    }
    final int? total = jsonConvert.convert<int>(json['total']);
    if (total != null) {
      listModel.total = total;
    }
    final int? totalPage = jsonConvert.convert<int>(json['totalPage']);
    if (totalPage != null) {
      listModel.totalPage = totalPage;
    }

    final List<dynamic>? list =
        jsonConvert.convert<List<dynamic>>(json['list']);
    if (list != null) {
      listModel.list = list.compactMap((element) {
        if (element == null) {
          return null;
        }
        final String type = T.toString();
        if (type == (double).toString() ||
            type == (int).toString() ||
            type == (String).toString()) {
          return element as T;
        } else {
          return JsonConvert.fromJsonAsT<T>(element);
        }
      });
    }
    return listModel;
  }

这里的逻辑还是比较简单的,new 出一个泛型类
final ListModel<T> listModel = ListModel<T>();
然后单字段解析,最后对与泛型类

final List<dynamic>? list =
        jsonConvert.convert<List<dynamic>>(json['list']);
    if (list != null) {
      listModel.list = list.compactMap((element) {
        if (element == null) {
          return null;
        }
        final String type = T.toString();
        if (type == (double).toString() ||
            type == (int).toString() ||
            type == (String).toString()) {
          return element as T;
        } else {
          return JsonConvert.fromJsonAsT<T>(element);
        }
      });
    }
注意要先对其解析普通类型,因为 jsonConvert 生成的方法中不支持解析基本类型

compactMap 是我封装的去空 map 方法

List<T> compactMap<T>(T? toElement(E element)) {
    List<T> temp = [];
    for (var item in this) {
      var toT = toElement(item);
      if (toT != null) {
        temp.add(toT);
      }
    }
    return temp;
  }

这样,你就可以直接支持一个 ListModel 泛型类解析了

另一个简单方法

但是,前面折腾了那么多,绕来绕去,云里雾里的,如果你不喜欢在 fromJson 中处理的话,实际上是有一个稍微有一点点麻烦(多写一行)但是又能够直接实现的方法.


因为 jsonConvert 不支持数组泛型但是支持确定的数组类型解析,不过我个人喜欢在 fromJson 内直接处理掉这个逻辑,况且目前的 JsonConvert(4.2.8)并不支持基础类型的解析,我所使用ListModel有时候还是需要解析字符串数组等等的业务的,所以只能我自己添加基础类型解析的逻辑.我也与FlutterJsonBeanFactory作者提过,作者也说明会考虑在未来版本加入基础类型解析的.

我目前的使用习惯是,使用 vscode 中的Json to Dart Model生成model 和 json 解析方法,用buildrunner监听文件改动,实时映射字段,手动添加 model 判断到 jsonconvert 值判断生成(这一步,大家可以随便找个空项目,用Android Studio 的FlutterJsonBeanFactory去生成 json_convert 文件的类型判断,复制过来即可.

就酱,下次再聊O(∩_∩)O~

相关文章

  • flutter 中 Json 泛型类数据处理

    如果你目前正在使用 flutter 作为你的开发语言,那么你一定会碰到我取的这个标题所述的问题. 问题 为什么呢,...

  • Java 泛型

    导读 移动开发知识体系总章(Java基础、Android、Flutter) 为什么会有泛型? 泛型类 泛型方法 泛...

  • Java 19-5.1泛型

    泛型类定义泛型类可以规定传入对象 泛型类 和泛型方法 泛型接口 如果实现类也无法确定泛型 可以在继承类中确定泛型:

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • 想理解泛型吗?看这一篇就够了!

    一、前言二、泛型类2.1 概述Java中泛型使用情况大致包括三种:泛型类、泛型接口、泛型方法 本节演示泛型类。 2...

  • Gson的使用详解

    添加依赖: 将json解析为List集合 将json解析为带泛型的实体类

  • 注解

    作用: 在类中定义泛型: 在方法中定义泛型: 给泛型设置通配符上限: 给泛型设置通配符下限: 泛型擦除: 兼容性:...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • Java反射(三)泛型

    一、泛型和Class类从JDK 1.5 后,Java中引入泛型机制,Class类也增加了泛型功能,从而允许使用泛型...

网友评论

      本文标题:flutter 中 Json 泛型类数据处理

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