@[toc]
手动序列化小项目
Map<String, dynamic> user = JSON.decode(json);
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');
手动JSON序列化是指在dart:convert中使用内置的JSON解码器。它将原始JSON字符串传递给JSON。decode()方法,然后在返回的Map<String,dynamic>中找到所需的值。它没有外部依赖项或其他设置,对于小型项目非常方便。
随着项目的增长,手动编写序列化逻辑可能变得不可管理且容易出错。如果在访问未提供的JSON字段时输入了错误的字段,代码将在运行时抛出错误。
{
"name": "John Smith",
"email": "john@example.com"
}
如果的项目没有很多JSON模型,并且希望快速测试它们,那么手动序列化可能会很方便。
在大型和中型项目中使用代码生成
代码生成的JSON序列化是指通过外部库自动生成序列化模板。它需要一些初始设置,并运行文件查看器从模型类生成代码。例如,json_Serializable和build_Value就是这样一个库。
该方法适用于较大的项目。不需要手写。如果访问带有拼写错误的JSON字段,将在编译时捕获该字段。代码生成的缺点是需要一些初始设置。此外,生成的源文件可能在项目导航器中显得杂乱。
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() =>
{
'name': name,
'email': email,
};
}
当有一个中型或大型项目时,可能希望使用代码生成JSON序列化。
Flutter中有GSON/Jackson/Moshi吗?
简单的答案是否定的
这样的库需要使用运行时反射,这在Flutter中是禁用的。反射会干扰Dart的树抖动使用树shaking_,我们可以在发布时“删除”未使用的代码。这可以显著优化应用程序的大小。
因为反射默认情况下使用所有代码_树抖动_这将很难工作。这些工具无法知道哪些小部件在运行时没有使用,因此冗余代码很难分割。使用反射时,应用程序大小无法轻松优化。
Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);
print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');
进程异步性
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text('Your current IP address is:'),
new Text('$_ipAddress.'),
spacer,
new RaisedButton(
onPressed: _getIPAddress,
child: new Text('Get IP address'),
),
],
),
它调用httpbin.com web服务测试API,然后该API使用的本地IP地址进行响应。请注意,使用了安全网络(HTTPS)。它调用httpbin.comWeb服务测试API。请注意,使用了安全网络请求(HTTPS)
运行Flutter创建以创建新的Flutter应用程序
将lib/main.art替换为以下内容:
@override
Widget build(BuildContext context) {
var spacer = new SizedBox(height: 32.0);
以下示例显示了如何在Flutter应用程序中解码HTTPS GET请求返回的JSON数据
,HTTP API在返回值中使用Dart Futures。我们建议使用async/await语法来调用API。
网络呼叫通常遵循以下步骤:
创建客户端
构造Uri
启动请求并等待请求。同时,可以配置请求头和正文。
关闭请求并等待响应
解码响应内容
其中几个步骤使用基于Future的API。上面每个步骤的示例API调用是:其中几个步骤使用了基于未来的API。
@override
void initState() {
super.initState();
_readCounter().then((int value) {
setState(() {
_counter = value;
});
});
}
Future<File> _getLocalFile() async {
// get the path to the document directory.
String dir = (await getApplicationDocumentsDirectory()).path;
return new File('$dir/counter.txt');
}
Future<int> _readCounter() async {
try {
File file = await _getLocalFile();
// read the variable as a string from the file.
String contents = await file.readAsString();
return int.parse(contents);
} on FileSystemException {
return 0;
}
}
格式化代码
自动设置代码格式
尽管可以遵循任何喜欢的风格-根据我们的经验,开发团队将:
拥有单一、共享的风格
此样式由自动格式化强制执行
在Android Studio和IntelliJ中自动格式化代码
Usage: flutter format <one or more paths>
-h, --help Print this usage information.
安装Dart插件(请参阅编辑器设置),以在AndroidStudio和IntelliJ中自动格式化代码。
要在当前源窗口中自动格式化代码,请右键单击代码窗口并选择使用dartfmt重新格式化代码。也可以使用快捷键来设置代码的格式。
自动格式化VS代码中的代码
import 'dart:io';
var httpClient = new HttpClient();
安装Dart Code插件(请参阅编辑器设置)以自动格式化VS代码中的代码。
要在当前源窗口中自动设置代码格式,请右键单击代码窗口并选择“设置文档格式”。也可以使用VS代码快捷键设置代码格式。
要在保存文件时自动格式化代码,请将editor.formatOnSave设置设置为true。
使用颤振命令自动格式化代码
void main() {
runApp(
new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(primarySwatch: Colors.blue),
home: new FlutterDemo(),
),
);
}
class FlutterDemo extends StatefulWidget {
FlutterDemo({Key key}) : super(key: key);
@override
_FlutterDemoState createState() => new _FlutterDemoState();
}
Flutter代码通常涉及构建相当深的树数据结构,例如在构建方法中。为了获得良好的自动格式,我们建议使用可选的尾随逗号。添加尾随逗号很简单:始终在函数、方法和构造函数的参数列表末尾添加尾随逗号,以保留编码。这将帮助自动格式化程序为Flutter样式代码插入适当的换行符。
这样,调用代码就不必担心JSON序列化。但是,模型类仍然是必需的。在生产应用程序中,我们希望确保序列化工作正常。在实践中,两个用户。来自Json和User。toJson方法需要适当的单元测试来验证正确的行为。
此外,在实际场景中,JSON对象很少如此简单,嵌套的JSON对象也并不少见。
尽管其他库可用,但我们在这个tutorial_Serializable包中使用了json。它是一个自动源代码生成器,可以为我们生成JSON序列化模板。
由于序列化代码不再由我们手写和维护,我们将在运行时最小化JSON序列化异常的风险。