Flutter dio 库封装并实现网络请求及 Json 数据解析示例

文章目录

      • dio
      • 基本使用
      • 封装使用
      • JSON 数据解析
        • 使用示例:

上篇文章介绍了本地存储数据,少量的数据我们才会放在本地,大部分的数据都是放在远程的服务器中。因此这就涉及到了如何和网络交互。Flutter dart:io库默认提供 HttpClient可以访问网络数据,但是httpClient使用相对复杂一些,于是Dart 官方提供的另一个网络请求库httpHttpClient 和 http这二者对于网络请求的定制化相对薄弱一些,于是Flutter中文开发者社区提供了另一个网络请求库dio ,由于dio使用简便,可定制的功能较丰富,文章这里直接介绍 dio 的使用和封装。

dio

README中是这么介绍的:dio是一个强大的Dart Http请求库,支持Restful APIFormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等…

基本使用

  1. 添加依赖: dio
dependencies:
  dio: ^3.0.9
  1. 导包使用
import 'package:dio/dio.dart';
 void getHttp() async {
    try {
      Response response = await Dio().get("http://www.baidu.com");
      setState(() {
        mContext = response.toString();
      });
    } catch (e) {
      print(e);
    }
  }

点击按钮之后将网络请求返回的response写入Text组件中。
Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第1张图片

一般网络请求库我们都会封装之后再使用。一是为了满足业务方便使用,二是为了扩展性后续有新的网络请求框架可以方便替换。

封装使用

查看 dio中的 README可以看出支持的功能还是很全的。
Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第2张图片
我们常用的也就get、post请求,以及Cookie的处理。

这里参考了两个大佬写的文章:

  • Flutter 网络请求封装之Dio(Cookie管理、添加拦截器、下载文件、异常处理、取消请求等)
  • Flutter Dio二次封装

具体的实现代码请查看 Flutter-WanAndroid lib/api包下的代码

封装之后使用的示例:

可以看出我们在请求的时候添加了加载框的效果。
Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第3张图片

在实际中我们几乎不直接返回Html格式的数据,一般都是返回定义好的Json数据,那么如何解析返回的Json数据呢?

JSON 数据解析

AndroidStudio中可以使用一些插件辅助将Json数据生成实体类对象。
我们可以从插件的下载数以及更新时间上去选择,FlutterJsonBeanFactory目前是使用最多且更新时间最近的。我是很久就安装了flutter_json_format,但是用着不顺手,后来换了FlutterJsonHelper之后用着还行就没更换了。下面就介绍怎么将网络返回的Json数据通过FlutterJsonHelper转为实体类。
Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第4张图片

使用示例:

获取 玩Android 网站 中 积分排行榜的接口,并将接口返回的 JSON 转为实体类,最后展示在页面上。

效果图如下:

实现过程如下:

  1. 为了方便 我直接在wanandroid上调用api获取返回的json
    Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第5张图片

  2. 创建coin.dart文件,将返回的json串复制,然后在coin.dart文件右键选择Generate-->JsonToDartClass,然后在弹窗中将json串粘贴进去,点击ok即可。生成的实体类最终如下图所示。
    Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第6张图片

  3. 数据实体类已经生成了,接下来我们来实现积分排行榜的展示页面。
    Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第7张图片
    主要是通过ListView来承载列表数据,列表中的item使用ListTile组件实现。阴影效果使用的是BoxShadow来实现。
    Flutter dio 库封装并实现网络请求及 Json 数据解析示例_第8张图片
    完整代码实现请查看 Flutter-WanAndroid 项目中的views/coin_rank_page/coin_rank_page.dart文件

  4. 实现上拉、下拉加载数据
    这里使用的是 EasyRefresh 实现。详细使用可查看 Flutter-WanAndroid 项目或者EasyRefresh项目首页介绍。

  5. 加载中弹窗
    由于每次默认返回30条数据,数据显示会有点延迟,导致页面出现空白。为了解决这个问题,我加入了加载中...弹窗。

弹窗使用的是封装之后的showDialog,由于showDialog中需要传递context,而我在initState()方法中是没法获取到context的,因此找到了 实现全局存储context的实现方式。

美滋滋的使用之后出现了下面的错误。

I/flutter (32591): 崩溃异常信息: setState() or markNeedsBuild() called during build.
I/flutter (32591): This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
I/flutter (32591): The widget on which setState() or markNeedsBuild() was called was:
I/flutter (32591):   Overlay-[LabeledGlobalKey#42a79]
I/flutter (32591): The widget which was currently being built when the offending call was made was:

具体原因看错误也没看懂,搜索一圈之后看到答案说只要给弹窗加个延迟即可。
类似下面的代码:

Future.delayed(Duration(milliseconds: 200)).then((e) {
  DialogManager.showBasicDialog(NavigationService.mContext, "正在加载中...");
});

以上就是整个示例的实现过程,具体代码可移步 Flutter-WanAndroid 项目查看

你可能感兴趣的:(Flutter,笔记)