前面讲完了常用的部件,BLoC
模式,数据持久化等常用的,今天再介绍个重头戏 —— 网络请求
HttpClient
HttpClient
是 dart
自带的网络请求方式,在 dart:io
包下。使用 HttpClient
作为请求分以下几个步骤
创建 HttpClient 实例
1
HttpClient client = HttpClient();
打开连接,并设置一些头参数,请求参数等
1
2
3
4
5
6
7
8
9
10
11
12// 如果 url 中没有查询参数可直接创建
Uri uri = Uri.parse('https://www.xxx.com');
// 如果存在查询参数则在 Uri 中添加
Uri uri = Uri(scheme: 'https', host: 'www.xxx.com', queryParameters: {'a': 'AAA'});
// 打开连接
HttpClientRequest request = await client.getUrl(uri);
request.headers.add('token', 'Bear ${'x' * 20}'); // 添加头部 token 信息
// 如果是 post 或者 put 请求,通过 `add` 添加请求体
// 因为 `add` 方法需要传入 `List<int>` 参数,可以通过 utf8.encode 进行编码
request.add(utf8.encode('{"a": "aaa"}'));
// 也可以通过添加流的方式进行添加
request.addStream(input);连接服务器
1
2
3// 设置 request 后通过 request.close() 获取一个响应对象 HttpClientResponse,
// 包括响应头,响应内容等
HttpClientResponse response = await request.close();读取服务器响应内容
1
String responseBody = await response.transform(utf8.decoder).join();
关闭实例
1
client.close();
例如我们要去请求 Bird.so
的首页并显示,我们可以这么实现
1 | _httpClientRequest() async { |
最后实现的效果
很显然,用 HttpClient
请求相对来说是个非常麻烦的过程,如果要涉及到文本上传之类的,那么就会更麻烦了,所以这边引入一个网络请求的插件 dio
,写本文的时候版本为 2.1.0
Dio
dio 是个非常强大的网络请求库,他的方式类似 OkHttp
,我们可以直接查看官方文档,使用方式非常简单,创建一个 Dio
实例,然后就可以通过 get
,post
等方式发起请求,返回 Future<Response>
,而且支持多个并发请求,可以设置返回响应的类型,监听上传下载进度等等,看着就很给力。对于简单的方式,这边就不做太多介绍,主要讲下拦截器,也是非常给力的一部分。比如我们需要请求这么个接口 https://randomuser.me/api/
这个接口通过 get
请求,可以加入任意的查询参数。比如我们需要实现一个请求加解密的过程,如果每次都在上传参数或者返回请求的时候去加密,解密的话,就做了非常多无用功了,那么这时候拦截器就派上用场了。先定义下加解密的规则,上传的参数统一转为小写,不存在大写,请求回的数据,不能含有 info
字段。看下如何实现
1 | _dioRequest() async { |
看下最后的显示信息
请求体的头部成功加上了 authorization
参数,请求的参数全部变为小写,返回的信息也把 info 字段值去除。在很多时候,请求接口后,需要将 json 转换成 pojo 类来处理,可以通过 json_serializable
这个三方插件实现,这边提供文章 Flutter Json自动反序列化,当然这种方式比较麻烦,这里推荐个 Android Studio
下的插件 dart_json_format
直接搜索就可以,如果用的是 Vitual Code
或者别的不是 JetBrains
系列的,这里有个转换的网址 JsonToDart。
以上代码查看 http_main.dart 文件
实践一下下
不知道小伙还记得前面讲的 BLoC
没有,忘了可以查看 Flutter 状态管理及 BLoC,这里结合 BLoC
和 Dio
实现界面和逻辑分离的小例子,接口使用前面提到的 https://randomuser.me/api/
接口。网络应该是比较常用的,所以对其进行一些封装还是很有必要的,这边提供下我自己封装的方法
1 | import 'package:dio/dio.dart'; |
封装后就可以愉快的调用了,如果有别的请求方式后期可以继续扩展。继续看代码,创建一个 application.dart
文件,用于存放全局参数
1 | class Application { |
并在 main()
方法中进行初始化,接下来就可以直接使用
1 | void main() { |
看下最后的实现效果吧,刚进入没有数据则通过转圈圈提示,加载完数据后,点击头像更换下个
实现 BLoC
需要有一个管理类
1 | class UserBloc extends BaseBloc { |
设置好管理类后,就可以来编写界面了,界面也比较简单
1 | class UserPageDemo extends StatelessWidget { |
以上代码查看 bloc_network 包下的所有文件