成都网站建设设计

将想法与焦点和您一起共享

flutter网络库,flutter 网络框架

Flutter Dio源码分析(四)--封装

Flutter Dio源码分析(一)--Dio介绍

成都创新互联公司是一家专业提供海东企业网站建设,专注与成都网站制作、成都做网站、外贸营销网站建设H5场景定制、小程序制作等业务。10年已为海东众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。

Flutter Dio源码分析(二)--HttpClient、Http、Dio对比

Flutter Dio源码分析(三)--深度剖析

Flutter Dio源码分析(四)--封装

Flutter Dio源码分析(一)--Dio介绍视频教程

Flutter Dio源码分析(二)--HttpClient、Http、Dio对比视频教程

Flutter Dio源码分析(三)--深度剖析视频教程

Flutter Dio源码分析(四)--封装视频教程

github仓库地址

本文会手把手教你该怎么去封装一个类库,平时在我们的工作中都是拿着别人的造好的轮子在使用,这篇文章将带你怎么去自己造轮子,以后再碰到别的类库需要对其进行封装的时候提供一个的思路和方法。

在前面的文章中,我们对 Dio 的基本使用、请求库对比、源码分析,我们知道 Dio 的使用非常的简单,那为什么还需要进行封装呢?有两点如下:

当组件库方法发生重要改变需要迁移的时候如果有多处地方用到,那么需要对使用到的每个文件都进行修改,非常的繁琐而且很容易出问题。

当不需要 Dio 库的时候,我们可以随时方便切换到别的网络请求库,当然 Dio 目前内置支持使用第三方库的适配器。

因为一个应用程序基本都是统一的配置方式,所以我们可以针对 拦截器 、 转换器 、 缓存 、 统一处理错误 、 代理配置 、 证书校验 等多个配置进行统一管理。

因为我们的应用程序在每个页面中都会用到网络请求,那么如果我们每次请求的时候都去实例化一个 Dio ,无非是增加了系统不必要的开销,而使用单例模式对象一旦创建每次访问都是同一个对象,不需要再次实例化该类的对象。

这是通过静态变量的私有构造器来创建的单例模式

我们对 超时时间 、 响应时间 、 BaseUrl 进行统一设置

因为不管是 get() 还是 post() 请求, Dio 内部最终都会调用 request 方法,只是传入的 method 不一样,所以我们这里定义一个枚举类型在一个方法中进行处理

我们已经把 Restful API 风格简化成了一个方法,通过 DioMethod 来标明不同的请求方式。在我们平时开发的过程中,需要在请求前、响应前、错误时对某一些接口做特殊的处理,那我们就需要用到拦截器。 Dio 为我们提供了自定义拦截器功能,很容易轻松的实现对请求、响应、错误时进行拦截

我们发现虽然 Dio 框架已经封装了一个 DioError 类库,但如果需要对返回的错误进行统一弹窗处理或者路由跳转等就只能自定义了

在我们发送请求的时候会碰到几种情况,比如需要对非open开头的接口自动加上一些特定的参数,获取需要在请求头增加统一的 token

在我们请求接口前可以对响应数据进行一些基础的处理,比如对响应的结果进行自定义封装,还可以针对单独的 url 做特殊处理等。

我们看了转换器的介绍,发现和拦截器的功能差不多,那为什么还要存在转换器,有两点:

执行流程: 请求拦截器 请求转换器 发起请求 响应转换器 响应拦截器 最终结果 。

只会被用于 'PUT'、 'POST'、 'PATCH'方法,因为只有这些方法才可以携带请求体(request body)

会被用于所有请求方法的返回数据。

在开发过程中,客户端和服务器打交道的时候,往往会用一个 token 来做校验,因为每个公司处理刷新token的逻辑都不一样,我这里举一个简单的例子

为什么我们需要有取消请求的功能,如果当我们的页面在发送请求时,用户主动退出当前界面或者app应用程序退出的时候数据还没有响应,那我们就需要取消该网络请求,防止不必要的错误。

由 服务器生成 的 一小段文本信息 ,发送给浏览器,浏览器把 cookie 以kv形式保存到本地 某个目录下的文本文件内,下一次请求同一网站时会把该 cookie 发送给服务器。

cookie 的使用需要用到两个第三方组件 dio_cookie_manager 和 cookie_jar

因为在我们平时的开发过程中,会碰到一种情况,在进行网络请求时,我们希望能正常访问到上次的数据,对于用户的体验比较好,而不是展示一个空白的页面,该缓存主要是 《Flutter实战》网络接口缓存 提供参考。

我们在程序退出后内存缓存将会消失,所以我们用 shared_preferences 进行磁盘缓存数据。

在我们用flutter进行抓包的时候需要配置 Dio 代理。由 DefaultHttpClientAdapter 提供了一个 onHttpClientCreate 回调来设置底层 HttpClient 的代理。

用于验证正在访问的网站是否真实。提供安全性,因为证书和域名绑定,并且由根证书机构签名确认。

日志打印主要是帮助我们开发时进行辅助排错

Flutter 之网络请求Dio, FormData, 表单网络请求, x-www-form-urlencoded

网络请求, 先想到的是dart官方维护的 http 库. 由于我们项目组网络请求都采用的表单结构, http 貌似不支持表单格式的网络请求; 后来查看 dio 库, 发现支持 FormData , 完美解决!

官方表单网络请求示例:

比葫芦画瓢, 尝试下

Flutter初探--常用依赖包

国外地址:

国内镜像:

以 flutter_screenutil 为例

路由框架 annotation_route

状态管理 provider

UI适配 flutter_screenutil

刷新控件 flutter_easyrefresh

网络请求 dio

toast控件 fluttertoast

图表库 charts_flutter

网络监听 connectivity

事件总线 event_bus

日历组件 table_calendar

官方webview webview_flutter

第三方webview flutter_webview_plugin

该篇文章为常用依赖包总结,用来记录所需要的常用依赖包,后续会不断扩充内容~

flutter 网络请求dio的简单使用以及请求头参数的自定义

dio的使用方式有很多,我就只选出我认为最好用的api方式做下记录,把get成post就是post请求了,网络请求都用的百度的api,实际上的response没有任何意义,所以只要打印出response有值即可。

1.最简单的请求例子,网络请求是异步的所以用async await

2.带有参数的get请求

3.自定义请求头,可定义的请求头dart已经为我们提供了专门的类存了对应的字符,引入以下库,就能使用 HttpHeaders

一般我们请求接收到的数据是json格式,如'accept: application/json',我们就可以这样自定义请求头

4.使用Baseoptions

其他详细参数设置参考如下:

Flutter 开发笔记

下面这种情况下,为 InkWell 设置的 splashColor 不会生效:

需要用 Material 去除背景色,然后将颜色设置在 InkWell 外部:

在 Dialog builder 中使用 WillPopScope 禁用返回键返回:

注意:使用此方法同时也会禁用 iOS 上的手势滑动返回功能,推荐判断平台后再使用。

修改对话框中的复选框状态,最简便的方法是通过 Element 中的 markNeedsBuild 方法:

当然,更推荐的做法是通过 StatefulBuilder ,然后就可以在 Dialog 中调用 setState 方法了,不过在调用 setState 时需要判断 Dialog 是否已经关闭,否则会造成 setState() called after dispose() 的错误,可以通过添加一个标志位来解决,如下:

在 Web 中加载网络图片有时会失败,遇到这样的报错: Exception caught by image resource service... ,造成该错误的原因通常是,图片跨域了(见 跨域资源共享 )。最简单的解决办法是, 使用 HTML 渲染加载 ,而不是默认的 CanvasKit。

Flutter 中所有的 list 默认都是没有 ScrollBar 的,必须使用 ScrollBar 组件。ScrollBar 组件通过监听 ScrollView 的 ScrollNotification 来刷新位置,所以 List 的长度必须是固定的。

当使用 WebView 等高度不定的组件时会出现内容被截断的情况,通常可以使用 NestedScrollView 来解决该问题,需要在 WebView 外部嵌套 SingleChildScrollView。

虽然使用了缓存,而且也是用 builder 加载图片的,但是发现一个现象:滑动屏幕后图片短暂消失并重新加载了。图片高度很高时这种现象更加明显,其原因是超出屏幕范围一定距离的组件被重新渲染了。解决方法是在 ListView 上设置 cacheExtent 参数:

该参数的作用是改变超出屏幕高度后继续渲染的范围(以像素为单位),比如设置成 9999 后意味着超出屏幕 10000 像素以内的内容都会被保留下来。

借助 IntrinsicHeight 组件:

另外,IntrinsicHeight 还可以用于 Dialog 或者 BottomSheet 中,使得其中的元素 显示内在元素的高度 ,从而避免元素因为约束的存在而不显示或者高度太高(比如在使用了 Column 或者 Row 的时候)。

在通过 Uri 的 queryParameters 获取 query 参数时,发现有些链接会抛出下面异常:

造成该异常的原因是 Uri 默认使用 utf-8 解码超链接字符串,如果链接中包含非 utf-8 字符,就会造成上面的错误,相关 issue 见: issue #31621 。目前该 issue 处于 open 的状态,暂时的解决办法是,在所有使用到 queryParameter 的地方用 try..catch 捕捉可能抛出的异常。

Flutter 开发非常依赖各种官方或第三方的插件,而在使用这些插件时多少都会遇到一些问题,大部分问题都可以通过搜索和查找 issue 来解决。这里记录下一些我在使用部分插件时遇到的问题及其解决方法。

目前该库没有图片加载完成的回调(见 issue #545 ),不过我们可以通过在 imageBuilder 中来添加回调:

这是一个应用内更新插件,安卓 10 以上安装时需要在 manifest 中添加以下内容:

目前功能最强大的 WebView 插件,基本能满足绝大部分移动端网页加载的需求,而且可定制化程度高。

一般通过 CookieManager 修改 Cookie,拦截请求并修改请求对象的 Header 不会生效。

InAppWebViewOptions 的 userAgent 只在 iOS 上生效,而 applicationNameForUserAgent 只在 Android 上生效,所以最好的做法是分平台设置 InAppWebViewOptions ,而且需要注意,由于设置 userAgent 后会覆盖默认的 UserAgent,所以如果需要在默认的 UserAgent 上添加其它参数,iOS 上需要通过 InAppWebViewController.getDefaultUserAgent() 获取默认 UserAgent 参数,而 Android 不需要添加。

如果图片源或者请求是 http 的,为了在 Android 上正常加载请求,必须在 AndroidInAppWebViewOptions 中将 mixedContentMode 设置为 AndroidMixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW 。

当我们想要设置全屏图片的时候,由于默认的 Constraint 会将图片居中显示,所以图片四周会留有空隙。为了去除这个限制,我们需要 Xcode 中打开 LaunchScreen.storyboard,然后在 View Controller 的 View 和 LaunchImage 上的 Safe Area 去掉。

具体设置方法:右侧 Inspector 面板 Show the Size inspector 解选 Layout Margins 中的 Safe Area Relative Margins,拖动图片占满全屏,然后根据 View Controller Scene 的 Warning,更新 Constraint 就可以了。

在集成某些三方库之后,在使用命令行运行 iOS 模拟器的时候可能会遇到下面这个报错:

这是因为 iOS 模拟器未来将会兼容 arm64 架构,但是目前还不支持,所以我们需要修改 Build Setting 使得能够在 x86_64 的模拟器上运行,操作步骤见 这里 。

Flutter的Dio网络请求封装

在yaml文件里边添加如下依赖

新建一个network_config.dart文件存放网络配置

ApiResponse是之前定义的公共接口返回实体 Flutter的Json数据解析之FlutterJsonBeanFactory插件

主要是对http异常和业务异常进行处理。

上述封装后,如果业务存在多个请求依赖调用,就需要统一的处理错误。

Dio支持自定义拦截器,继承 Interceptor ,重写 onRequest 和 onResponse 方法就行。

在初始化dio的地方,把拦截器加入dio对象的拦截器集合 dio.interceptors 中就行。

可以通过自定义的拦截器实现,也可以引入 pretty_dio_logger 库。

fastmock 上新建自己的项目,接口配置如下:

发起请求:

效果展示:

参考文章:


当前文章:flutter网络库,flutter 网络框架
当前URL:http://chengdu.cdxwcx.cn/article/phciss.html