Flutter数据序列化插件enough_serialization的使用
Flutter数据序列化插件enough_serialization的使用
1. 安装
首先,在你的pubspec.yaml
文件中添加enough_serialization
依赖:
dependencies:
enough_serialization: ^1.4.0
2. 使用方法
enough_serialization
提供了两种序列化模式:
- 继承
SerializableObject
或实现Serializable
:适用于需要完全控制和处理复杂情况的场景。你需要将字段值存储在一个动态映射(Map<String, dynamic>
)中。 - 实现
OnDemandSerializable
:仅在需要时读取和写入字段值到/从动态映射中。这种方式适用于简单的情况,但对嵌套结构有局限性。
3. 示例代码
简单示例
当只有基本字段(如String
、int
、double
、bool
)时,使用非常简单:
import 'package:enough_serialization/enough_serialization.dart';
class SimpleArticle extends SerializableObject {
String? get name => attributes['name'];
set name(String? value) => attributes['name'] = value;
int? get price => attributes['price'];
set price(int? value) => attributes['price'] = value;
double? get popularity => attributes['popularity'];
set popularity(double? value) => attributes['popularity'] = value;
}
void simpleExample() {
print('simple example:');
final article = SimpleArticle()
..name = 'Remote Control'
..price = 2499
..popularity = 0.1;
final serializer = Serializer();
final json = serializer.serialize(article);
print('serialized article: $json');
final inputJson =
'{"name": "Remote Control", "price": 2499, "popularity": 0.1}';
final deserializedArticle = SimpleArticle();
serializer.deserialize(inputJson, deserializedArticle);
print('name: ${deserializedArticle.name}');
print('price: ${deserializedArticle.price}');
print('popularity: ${deserializedArticle.popularity}');
}
枚举示例
枚举类型不能自动序列化或反序列化,需要注册一个转换函数:
enum ArticleArea { electronics, music }
class ArticleWithEnum extends SerializableObject {
ArticleWithEnum() {
transformers['area'] = (value) =>
value is ArticleArea ? value.index : ArticleArea.values[value];
}
ArticleArea? get area => attributes['area'];
set area(ArticleArea? value) => attributes['area'] = value;
String? get name => attributes['name'];
set name(String? value) => attributes['name'] = value;
}
void enumExample() {
print('enum example:');
final article = ArticleWithEnum()
..area = ArticleArea.electronics
..name = 'Remote Control';
final serializer = Serializer();
final json = serializer.serialize(article);
print('serialized article: $json');
final inputJson = '{"area": 0, "name": "Remote Control"}';
final deserializedArticle = ArticleWithEnum();
serializer.deserialize(inputJson, deserializedArticle);
print('area: ${deserializedArticle.area}');
print('name: ${deserializedArticle.name}');
}
嵌套对象和复杂列表
对于嵌套对象和复杂列表,需要在objectCreators
中注册创建函数:
class Article extends SerializableObject {
Article() {
transformers['area'] = (value) =>
value is ArticleArea ? value.index : ArticleArea.values[value];
}
ArticleArea? get area => attributes['area'];
set area(ArticleArea? value) => attributes['area'] = value;
String? get name => attributes['name'];
set name(String? value) => attributes['name'] = value;
int? get price => attributes['price'];
set price(int? value) => attributes['price'] = value;
}
class ElectronicsArticle extends Article {
ElectronicsArticle() {
area = ArticleArea.electronics;
}
String? get recommendation => attributes['recommendation'];
set recommendation(String? value) => attributes['recommendation'] = value;
}
class MusicArticle extends Article {
MusicArticle() {
area = ArticleArea.music;
objectCreators['band'] = (map) => Band();
}
Band? get band => attributes['band'];
set band(Band? value) => attributes['band'] = value;
}
class Band extends SerializableObject {
String? get name => attributes['name'];
set name(String? value) => attributes['name'] = value;
int? get year => attributes['year'];
set year(int? value) => attributes['year'] = value;
Band({String? name, int? year}) {
this.name = name;
this.year = year;
}
}
class Order extends SerializableObject {
Order() {
objectCreators['articles'] = (map) => <Article>[];
objectCreators['articles.value'] = (map) {
final int areaIndex = map!['area'];
final area = ArticleArea.values[areaIndex];
switch (area) {
case ArticleArea.electronics:
return ElectronicsArticle();
case ArticleArea.music:
return MusicArticle();
}
return Article();
};
}
List<Article>? get articles => attributes['articles'];
set articles(List<Article>? value) => attributes['articles'] = value;
}
void complexExample() {
print('complex example:');
final order = Order()
..articles = [
ElectronicsArticle()
..name = 'CD Player'
..price = 3799
..recommendation = 'Consider our streaming option, too!',
ElectronicsArticle()
..name = 'MC Tape Deck'
..price = 12399
..recommendation = 'Old school, like it!',
MusicArticle()
..name = 'The white album'
..price = 1899
..band = Band(name: 'Beatles', year: 1962)
];
final serializer = Serializer();
final json = serializer.serialize(order);
print('order: $json');
final inputJson =
'{"articles": [{"area": 0, "name": "CD Player", "price": 3799, "recommendation": "Consider our streaming option, too!"}, '
'{"area": 0, "name": "MC Tape Deck", "price": 12399, "recommendation": "Old school, like it!"}, '
'{"area": 1, "name": "The white album", "price": 1899, "band": {"name": "Beatles", "year": 1962}}]}';
final deserializedOrder = Order();
serializer.deserialize(inputJson, deserializedOrder);
for (var i = 0; i < deserializedOrder.articles!.length; i++) {
final article = deserializedOrder.articles![i];
print('$i: area: ${article.area}');
print('$i: name: ${article.name}');
print('$i: price: ${article.price}');
if (article is ElectronicsArticle) {
print('$i: recommendation: ${article.recommendation}');
} else if (article is MusicArticle) {
print('$i: band-name: ${article.band!.name}');
print('$i: band-year: ${article.band!.year}');
}
}
}
嵌套映射
对于嵌套映射,同样需要在objectCreators
中注册创建函数,并为非字符串键提供转换函数:
class MappedArticle extends SerializableObject {
MappedArticle() {
objectCreators['news-by-year'] = (map) => <int, String>{};
transformers['news-by-year.key'] =
(value) => value is int ? value.toString() : int.parse(value);
}
String? get name => attributes['name'];
set name(String? value) => attributes['name'] = value;
Map<int, String>? get newsByYear => attributes['news-by-year'];
set newsByYear(Map<int, String>? value) => attributes['news-by-year'] = value;
}
void mapExample() {
print('map example:');
final newsByYear = {
2020: 'Corona, Corona, Corona...',
2021: 'The end of a pandemia',
2022: 'Climate change getting really serious'
};
final article = MappedArticle()
..name = 'My Article'
..newsByYear = newsByYear;
final serializer = Serializer();
final json = serializer.serialize(article);
print('article with map: $json');
final inputJson =
'{"name": "My Article", "news-by-year": {"2020": "Corona, Corona, Corona...", "2021": "The end of a pandemic", "2022": "Climate change getting really serious"}}';
final deserializedArticle = MappedArticle();
serializer.deserialize(inputJson, deserializedArticle);
print('deserialized article: ${article.name}');
for (final key in article.newsByYear!.keys) {
print('$key: ${article.newsByYear![key]}');
}
}
按需序列化
如果你不想使用动态映射来存储字段值,可以实现OnDemandSerializable
接口:
class OnDemandArticle implements OnDemandSerializable {
String? name;
Map<int, String>? newsByYear;
String serialize() {
final serializer = Serializer();
final json = serializer.serializeOnDemand(
this,
transformers: {
'news-by-year.key': (value) =>
value is int ? value.toString() : int.parse(value),
},
);
return json;
}
void deserialize(String json) {
final serializer = Serializer();
serializer.deserializeOnDemand(
json,
this,
transformers: {
'news-by-year.key': (value) =>
value is int ? value.toString() : int.parse(value),
},
objectCreators: {
'news-by-year': (map) => <int, String>{},
},
);
}
@override
void write(Map<String, dynamic> attributes) {
attributes['name'] = name;
attributes['news-by-year'] = newsByYear;
}
@override
void read(Map<String, dynamic> attributes) {
name = attributes['name'];
newsByYear = attributes['news-by-year'];
}
}
void onDemandExample() {
print('on demand example:');
final newsByYear = {
2020: 'Corona, Corona, Corona...',
2021: 'The end of a pandemia',
2022: 'Climate change getting really serious'
};
final article = OnDemandArticle()
..name = 'My Article'
..newsByYear = newsByYear;
final json = article.serialize();
print('on demand article: $json');
final inputJson =
'{"name": "My Article", "news-by-year": {"2020": "Corona, Corona, Corona...", "2021": "The end of a pandemic", "2022": "Climate change getting really serious"}}';
final deserializedArticle = OnDemandArticle();
deserializedArticle.deserialize(inputJson);
print('deserialized article: ${article.name}');
for (final key in article.newsByYear!.keys) {
print('$key: ${article.newsByYear![key]}');
}
}
4. 主函数
最后,将所有示例整合到main
函数中:
void main() {
simpleExample();
print('');
enumExample();
print('');
complexExample();
print('');
mapExample();
print('');
onDemandExample();
}
更多关于Flutter数据序列化插件enough_serialization的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据序列化插件enough_serialization的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用enough_serialization
插件进行数据序列化的示例代码。enough_serialization
是一个用于Flutter的数据序列化库,它允许你轻松地将Dart对象转换为JSON格式,以及从JSON格式反序列化回Dart对象。
步骤 1: 添加依赖
首先,你需要在pubspec.yaml
文件中添加enough_serialization
的依赖:
dependencies:
flutter:
sdk: flutter
enough_serialization: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
步骤 2: 定义数据模型
接下来,定义一个需要序列化的数据模型。你需要让这个类实现Serializable
接口,并且使用@Serializable()
注解。
import 'package:enough_serialization/enough_serialization.dart';
@Serializable()
class User {
final String name;
final int age;
User({required this.name, required this.age});
// 工厂构造函数用于反序列化
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
// 方法用于序列化
Map<String, dynamic> toJson() => _$UserToJson(this);
}
注意:_$UserFromJson
和_$UserToJson
是自动生成的方法,用于处理序列化和反序列化。
步骤 3: 生成序列化代码
在项目根目录下运行以下命令来生成序列化代码:
flutter pub run build_runner build
这将生成需要的序列化代码文件。
步骤 4: 使用序列化功能
现在你可以在你的Flutter应用中使用这些序列化功能了。
void main() {
// 创建一个User对象
User user = User(name: 'Alice', age: 30);
// 将User对象序列化为JSON
Map<String, dynamic> userJson = user.toJson();
print('Serialized User: $userJson');
// 从JSON反序列化为User对象
User deserializedUser = User.fromJson(userJson);
print('Deserialized User: ${deserializedUser.name}, Age: ${deserializedUser.age}');
}
完整示例
以下是完整的代码示例,包括所有步骤:
// pubspec.yaml
dependencies:
flutter:
sdk: flutter
enough_serialization: ^最新版本号 # 请替换为实际的最新版本号
build_runner: ^最新版本号 # build_runner是生成序列化代码的工具
// user_model.dart
import 'package:enough_serialization/enough_serialization.dart';
part 'user_model.g.dart'; // 自动生成的文件
@Serializable()
class User {
final String name;
final int age;
User({required this.name, required this.age});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
// main.dart
import 'package:flutter/material.dart';
import 'user_model.dart';
void main() {
// 创建一个User对象
User user = User(name: 'Alice', age: 30);
// 将User对象序列化为JSON
Map<String, dynamic> userJson = user.toJson();
print('Serialized User: $userJson');
// 从JSON反序列化为User对象
User deserializedUser = User.fromJson(userJson);
print('Deserialized User: ${deserializedUser.name}, Age: ${deserializedUser.age}');
// Flutter应用入口(仅为示例,实际使用时需构建UI)
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter Serialization Demo')),
body: Center(child: Text('Check console for serialization output')),
),
));
}
确保在项目根目录下运行flutter pub run build_runner build
来生成序列化代码文件user_model.g.dart
。
以上就是在Flutter项目中使用enough_serialization
进行数据序列化的完整示例。希望这对你有所帮助!