效率翻倍!大型Flutter项目快速实现JSON转Model实战

3,754 阅读4分钟

一、前言

在原生应用开发中,我们通常会使用YYModelSwiftyJSONGSON等库实现JSON解析,并使用JSONConverter等类似工具实现JSON自动转模型,极大的提高工作效率。 但在Flutter开发中,却并没有类似的解析库给我们使用,因为这样的库需要使用运行时反射,这在 Flutter 中是禁用的。运行时反射会干扰 Dart 的 tree shaking,使用_tree shaking_,可以在 release 版中“去除”未使用的代码,这可以显著优化应用程序的大小。由于反射会默认应用到所有代码,因此_tree shaking_ 会很难工作,因为在启用反射时很难知道哪些代码未被使用,因此冗余代码很难剥离,所以 Flutter 中禁用了 Dart 的反射功能,而正因如此也就无法实现动态转化 Model 的功能。

二、json_serializable

虽然不能在Flutter中使用运行时反射,但官方提供了类似易于使用的API,它是基于代码生成库实现,json_serializable package,它是一个自动化的源代码生成器,可以生成JSON序列化模板,由于序列化代码无需手写和维护,将运行时产生JSON序列化异常的风险降至最低,使用方法如下:

1. 在项目中添加json_serializable

要包含json_serializable到我们的项目中,需要一个常规和两个开发依赖项。简而言之,开发依赖项是不包含在我们的应用程序源代码中的依赖项。 通过此链接可以查看这些所需依赖项的最新版本 。

json_serializable.png

在您的项目根文件夹中运行 flutter packages get (或者在编辑器中点击 “Packages Get”) 以在项目中使用这些新的依赖项.

2. 以json_serializable的方式创建model类

让我们看看如何将我们的User类转换为一个json_serializable。为了简单起见,我们使用前面示例中的简化JSON model。

user.dart

import 'package:json_annotation/json_annotation.dart';

// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';

///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()
class User {
  String name;
  String email;

  User(this.name, this.email);

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

有了这个设置,源码生成器将生成用于序列化name和email字段的JSON代码。

如果需要,自定义命名策略也很容易。例如,如果我们正在使用的API返回带有_snake_case_的对象,但我们想在我们的模型中使用_lowerCamelCase_, 那么我们可以使用@JsonKey标注:

@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;

3. 运行代码生成程序

  • 一次性生成 通过在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的Model生成JSON序列化代码。 这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码。

  • 持续生成 虽然这非常方便,但如果我们不需要每次在model类中进行更改时都要手动运行构建命令的话会更好。 使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。我们可以通过flutter packages pub run build_runner watch在项目根目录下运行来启动_watcher_。 只需启动一次观察器,然后并让它在后台运行,这是安全的

4. 使用json_serializable模型

要通过json_serializable方式反序列化JSON字符串,我们不需要对先前的代码进行任何更改。

Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);

序列化也一样。调用API与之前相同。

String json = JSON.encode(user);

有了json_serializable,我们只需要编写User类文件 。源代码生成器创建一个名为user.g.dart的文件,它具有所有必需的序列化逻辑。 现在,我们不必编写自动化测试来确保序列化的正常工作 - 这个库会确保序列化工作正常。

三、 JSONConverter

如上面所写,即便使用了json_serializable,仍然需要手动编写模型类文件并逐一编写对应的模型属性,生产工作中一个项目可能会有几百个API, 如果全部手写依旧浪费大量摸鱼的时间,这里我们可以使用JSONConverter, 它可根据后台返回的JSON自动生成模型文件,配合json_serializable,可以非常方便的实现接口对接,模型文件一键生成,极大节省程序员的体力。

Flutter-JSONConverter.png 另外JSONConverter除了支持Flutter,还支持其他语言和第三方库,功能可能说非常丰富了。

JSONConverter.png

四、总结

生产项目中推荐使用json_serializable + JSONConverter 完成服务端返回的JSON数据解析工作,效率翻倍!!