只要咱们的app不是单机的,那么必然涉及到远程服务器数据请求。在flutter
中,发起请求已经有现成的包dio
了,使用起来也很是简练方便,如仍是不是很了解,能够点击查看dio的详细文档。javascript
发起请求,拿到服务端返回的json数据后,接下来的步骤是怎么样的。flutter
(应该说是Dart
)可不像javascript
那样,对json
天生友好。这就是本文要讲的主要内容。你将会学到:html
flutter
项目json
数据处理的详细步骤和踩坑提醒json_serializable
环节,命令行+工具,帮你自动化生成相关代码,无需手敲,无需手敲(重要的事情说两遍)请求回来数据后,下一步必然就是读取其中的数据信息,而后依此进行界面展现和逻辑处理了。java
若是返回来的是简单的数据,并且业务逻辑也很简单,那么其实处理方式也能够简单化,例如服务端返回数据以下:git
{
code: 200,
message: null,
value: true
}
复制代码
那么,你甚至能够这么处理:github
if (jsonStr.indexOf('true') != -1) {
// do something
}
复制代码
总结的说,在这种场景下面,使用正则表达式匹配或者简单字符串处理逻辑,进行简单快速的实现,也不失为一种好方法。正则表达式
可是,当数据结构足够复杂(例如:点击查看复杂数据示例),那么上述的方式显然就有点捉襟见肘了。shell
这个时候,就该轮到本文要讲述的重点,json
反序列化上场了。关于序列化和反序列化,能够上网查一下,有不少资料(实在不想查,好吧,这里有现成的,点击序列化凑合着看一下吧...)。json
在本文描述的业务场景下面,也能够简单理解为,咱们要作的,就是把经过dio
拿到的服务端json
字符串数据,转换为对象,而后就能够愉快的访问该对象中的字段值了。api
主要的步骤有两个:bash
json
字符串转换为Map
对象json_serializable
进行反序列化具体步骤以下:
参考下面代码,往pubspec.yaml
文件中添加json_annotation
、json_serializable
和build_runner
包。
dependencies:
flutter:
sdk: flutter
json_annotation: ^3.0.0
dev_dependencies:
flutter_test:
sdk: flutter
json_serializable: ^3.2.0
build_runner: ^1.6.5
复制代码
添加完,记得flutter packages get
xxxx.dart
(文件一,会在下文的代码中引用到)copy到项目中若是你已经看过其余相关文章,颇有多是要你根据json
数据写一个dart的实体类,其实,也能够的,选择你喜欢方式就好了。本文推荐工具生成,方便快捷,不易出错,哈哈。。。
若是,你还没来得及准备好试验的json
数据,点击本文为你提供的数据示例,copy到工具中,愉快的玩耍吧。
flutter packages pub run build_runner build
,命令执行完成,根据刚刚的xxxx.dart
生成xxxx.g.dart
(该文件生成后不要手动改,也无需引用,放着不动就是了)import 'dart:convert';
import 'package:xxxxxxx/xxxx.dart'; //引入上面说起的文件一
String jsonStr = '{"value":1}'; //你要进行反序列化的json字符串
Map<String ,dynamic> map = json.decode(jsonStr); //先转成Map
MyObject obj = MyObject.fromJson(map); //假设class名为MyObject,这个根据实际状况调整
print(obj.value);
复制代码
到此,基本就完成了数据的反序列化。上述代码中,主要是两个步骤:
MyObject
即引入的“文件一”中的类名,可根据实际状况进行调整。
也可能你会有疑问,既然原生已经提供了String to Map
,那么只作到这一步,而后使用map对象进行接下来的coding,ok吗。
其实,也是能够的,只是。。。,下面举个列子对比一下,便一目了然了。以该数据示例为例,下面两行代码,访问的字段是同样的:
print(homePageList.value[0].modules[0].items[1].title);
print(map.entries.elementAt(2).value[0].entries.elementAt(5).value[0].entries.elementAt(11).value[1].entries.elementAt(0).value);
复制代码
不知你喜欢哪一种方式呢。。。
按照上述的具体步骤,基本能够处理大部分的规则数据了,可是当你以数据示例为数据源,一步一步操做coding完,访问其中某些字段的值时,意想不到的事情发生了:
print(homePageList.value[0].modules[0].items[1].title); //正常打印
print(homePageList.value[0].modules[2].items[0].name); // 报错
复制代码
报错信息:
The following NoSuchMethodError was throw building BlockRowFrame(dirty):
Class 'Modules' has no instance getter 'title'.
...
复制代码
这是由于,数据每一项的结构不一致致使的。数据示例中,字段name
在前两个modules
的items
元素中并无,而在第三个modules
的items
元素中,却有了。
遇到这种状况,只须要在用工具生成的"文件一"中对应的class
,手动添加上对应的字段代码,而后再从新运行一次flutter packages pub run build_runner build --delete-conflicting-outputs
即可。
到此,关于flutter json
数据处理分享就讲完了。码字不易,以为此文对你有帮助的,麻烦点个赞鼓励鼓励。
若是还有不清楚的地方。。。
不要紧,源码伺候,点击flutter_examples访问对应的github项目,其中的“json格式请求结果反序列化与使用(dio & json_serializable demo)”实例,就是本文的代码实现!