Flutter对象序列化插件object_serialization的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter对象序列化插件object_serialization的使用

特性

一个支持循环引用且在对象通过多条路径被引用时保留身份的序列化库。

许多序列化库不处理循环引用;而这个库可以!大多数序列化库不保留身份;而这个库可以!也就是说,当 a 引用 bc,每个都引用 d 时,这个库会将相同的 d 安装到 bc 中。

  a
 / \
b   c
 \ /
  d

考虑以下代码,其中列表包含对同一个对象(这里是一个字符串)的两次引用:

final s = 'abc';
final list1 = [s, s];
assert(identical(list1.first, list1.last));

如果我们使用 jsonEncode()jsonDecode(),被引用的对象会被复制(丢失了对象的身份):

final buffer = jsonEncode(list1);
final list2 = jsonDecode(buffer) as List;
assert(identical(list2.first, list2.last));  // 失败!

但是使用 object_serialization 库,被引用的对象是相同的(保留了对象的身份):

final buffer = ObjectSerialization.encode(list1);
final list2 = ObjectSerialization.decode(buffer, {}) as List;
assert(identical(list2.first, list2.last));  // 成功!

使用方法

虽然少数简单对象可以自动处理,但更复杂的类应该实现或扩展 Serializable。这需要新增四个方法:

  • List<Object> get finalPropertiesList<Object> get transientProperties 用于获取可以用来重新创建对象的属性列表。

    • finalProperties 是在对象创建时必须提供的那些属性。
    • transientProperties 是所有其他属性。
  • 需要一个工厂函数来重新创建对象。

  • set transientProperties(List<Object> properties) 用于设置其他属性。

我们不能在创建对象时提供所有属性的原因是对象之间可能存在循环引用。例如,a 可以引用 bb 可以引用 a。然而,尽管存在循环引用,它们都不能同时是 final,因为其中一个必须存在才能被另一个使用。

查看测试文件以获取更多示例。

额外信息

如需贡献代码或报告问题,请访问 https://github.com/jgfoster/object_serialization

示例代码

import 'package:object_serialization/object_serialization.dart';

void main() {
  final s = 'abc';
  // 一个列表包含对同一个字符串的两次引用。
  final List<Object> list1 = [s, s];
  // 将列表添加到自身以形成循环引用。
  list1.add(list1);
  assert(identical(list1[0], list1[1]));
  assert(identical(list1, list1[2]));
  final buffer = ObjectSerialization.encode(list1);
  final list2 = ObjectSerialization.decode(buffer, {}) as List;
  // 对象身份被保留。
  assert(identical(list2[0], list2[1]));
  // 循环引用被保留。
  assert(identical(list2, list2[2]));
  print('Success!');
}

更多关于Flutter对象序列化插件object_serialization的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter对象序列化插件object_serialization的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用object_serialization插件进行对象序列化的示例代码。首先,确保你已经在pubspec.yaml文件中添加了object_serialization依赖:

dependencies:
  flutter:
    sdk: flutter
  object_serialization: ^x.y.z  # 替换为最新版本号

然后运行flutter pub get来安装依赖。

示例代码

  1. 定义模型类

    你需要定义一个可序列化的模型类。通常,这个类会包含一些字段,并且这些字段需要是可序列化的数据类型(如基本数据类型、列表、其他可序列化的类等)。

    import 'package:object_serialization/object_serialization.dart';
    
    [@Serializable](/user/Serializable)()
    class User {
      String name;
      int age;
      List<String> hobbies;
    
      User({required this.name, required this.age, required this.hobbies});
    
      factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
    
      Map<String, dynamic> toJson() => _$UserToJson(this);
    }
    

    注意:[@Serializable](/user/Serializable)()注解和生成的fromJsontoJson方法是通过插件在编译时自动生成的。

  2. 序列化和反序列化

    使用生成的fromJsontoJson方法来进行对象的序列化和反序列化。

    void main() {
      // 创建一个User对象
      User user = User(name: 'John Doe', age: 30, hobbies: ['Reading', 'Swimming']);
    
      // 将User对象序列化为JSON字符串
      String jsonString = jsonEncode(user.toJson());
      print('Serialized JSON: $jsonString');
    
      // 将JSON字符串反序列化为User对象
      Map<String, dynamic> jsonMap = jsonDecode(jsonString);
      User deserializedUser = User.fromJson(jsonMap);
    
      // 输出反序列化后的对象
      print('Deserialized User: ${deserializedUser.name}, Age: ${deserializedUser.age}, Hobbies: ${deserializedUser.hobbies}');
    }
    
  3. 运行项目

    确保你的Flutter项目结构正确,并且你已经按照上述步骤添加了依赖和代码。然后运行你的Flutter项目,你应该能在控制台看到序列化和反序列化的结果。

注意事项

  • 确保你使用的object_serialization版本与Flutter SDK兼容。
  • 如果你的模型类包含复杂的嵌套结构或自定义类型,你可能需要为这些类型也提供序列化和反序列化的实现。
  • 在使用插件生成的代码时,请确保你的IDE或编辑器支持Dart的编译时注解处理,以便正确生成序列化代码。

希望这个示例能帮助你在Flutter项目中成功使用object_serialization插件进行对象序列化。如果你遇到任何问题,请查阅插件的官方文档或提交问题到相关社区。

回到顶部