Flutter Http库Dio 2.1正式发布

Dio 是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等。目前Dio在pub上综合得分100分,排名已上榜pub首页(All Tab下) !同时Dio也是Github上最受欢迎的Flutter第三方库,项目地址:Dio-Github

从1.0发布至今,Dio受到了大量国内外开发者的关注,并收到了很多肯定和建议。为了让Dio功能更强大、让开发者使用起来更容易,我们综合了1.0中的各种反馈,对Dio进行了一次大的更新,为了让使用者在1.0和2.x之间有个过渡,我们将2.0.x-2.1.0作为预发布版在全网进行了接近两个月的公测。现在,很高兴的告诉大家,2.x的功能已经收敛、质量已经稳定,因此,今天我们正式发布Dio 2.x的第一个稳定版Dio v2.1.0

相比1.x,2.x在Restful API、拦截器、FormData等很多地方都进行了扩展和调整,除了这些,Dio在2.x中还引入Adapter层,为Mock接口数据和自定义底层网络库提供了支持。整体功能相比1.x有了很大的提升,因此我们强烈建议所有1.x用户都能升级到2.1。

功能介绍

请参考: https://github.com/flutterchina/dio

Dio V2.1.x 变更列表

Restful API

2.1中对所有Restful API的变化有:

  1. 支持Uri,在1.x中,Url只能是字符串,2.1中所有API都提供了对应支持Uri的版本,如get方法有dio.get(...)dio.gerUri(...)

  2. 所有方法都支持queryParameters,2.1标准化了参数语义,并允许所有请求都可以传query,而data只针对可以提交请求体的方法如post作为请求体提交。另外相对于Uri.queryParameters,我们对Restful API中的queryParameters的功能做了加强,主要有两个差异:

    • 参数值类型不同;前者只能接受Map<String, String|Iterable<String>>类型的参数,而后者可以接受Map<String, dynamic>类型,比如:

      dio.getUri(Uri(url, queryParameters: {"age":15})) //会抛出异常,Uri.queryParameter的value不能是int类型
      dio.get(url, queryParameters: {"age":15}); //这是OK的!
      
    • 编码方式有所差异; Uri.queryParameters编码方式遵循Dart SDK中的规则,而Restful API中的queryParameters编码方式和jQuery一致,如:

        dio.options.baseUrl="http://domain.com/";
        
        //下面请求的最终uri为:http://domain.com/api?selectedId=1&selectedId=2
        Response response = await dio.getUri(
          Uri(path: "api",queryParameters:  {"selectedId": ["1", "2"],});
        );
        //下面请求的最终uri为:https://flutterchina.club?selectedId%5B%5D=1&selectedId%5B%5D=2
        dio.get("api",queryParameters: {"selectedId": ["1", "2"], });
      
  1. 支持以Stream方式提交数据了;2.1中可以通过Stream的方式来提交二进制数据了,详细的示例可以参考这里

  2. 支持以二进制数组形式接收数据了;1.x中如果要以二进制形式接收响应数据则需要设置options.responseTypeResponseType.stream 来接收响应流,然后再通过读取响应流来获取完整的二进制内容,而2.x中只需要设置为ResponseType.bytes,则可直接获得响应流的而精致数组。

  3. API统一添加了onSendProgressonReceiveProgress 两个回调,用于监听发送数据和接收数据的具体精度,在1.x中只有在下载文件和上传formdata时才能监听进度,而2.x中所有接口都可以了。

拦截器

  1. 支持设置多个拦截器;

    这样我们就可以将一些功能单独抽离,比如打印请求/响应日志和cookie管理都可以单独封装在一个拦截器中,这样在解耦的同时可以提高代码的可复用度。

    2.1中拦截器是一个队列,拦截器将会按照FIFO顺序执行,如果队列中的某个拦截器返回了Response或Error,则请求结束,队列后面的拦截器将不会再被执行。

  2. 预置了打印请求/响应日志的LogInterceptor和管理cookie的CookieManager拦截器,开发者可以按需使用,如:

      dio.interceptors
        ..add(LogInterceptor(responseBody: false))
        ..add(CookieManager(CookieJar()));
    

FormData

1.x中,在提交FormData时会先将FormData转成一个二进制数组,然后再提交,这在FormData中的数据量比较大时(如包含多个大文件)在上传的过程中会比较占用内存。2.1中我们队FormData进行了增强,给FormData添加一个stream属性,它可以将FormData转为一个stream,在提交时无需一次性加载到内存。

同时FormData也添加了asBytes()asBytesAsync()length等方法、属性。

Response

Response中添加了一些关于重定向信息的字段,有isRedirectredirectsrealUri

TransFormer

2.x中对于DefaultTransformer添加了一个jsonDecodeCallback,通过它可以定制json解码器,这在flutter中非常有用,我们可以通过compute方法来在后台进行json解码,从而避免在UI线程对复杂json解码时引起的界面卡顿,详情请见这里

HttpClientAdapter

HttpClientAdapter是 Dio 和 HttpClient之间的桥梁。2.0抽象出了adapter层,可以带来两个主要收益:

  1. 实现Dio于HttpClient的解耦,这样可以方便的切换、定制底层网络库。
  2. 可以Mock数据;

Dio实现了一套标准的、强大API,而HttpClient则是真正发起Http请求的对象,两者并不是固定的一对一关系,我们完全可以在使用Dio时通过其他网络库(而不仅仅是dart HttpClient )来发起网络请求。我们通过HttpClientAdapter将Dio和HttpClient解耦,这样一来便可以自由定制Http请求的底层实现,比如,在Flutter中我们可以通过自定义HttpClientAdapter将Http请求转发到Native中,然后再由Native统一发起请求。再比如,假如有一天OKHttp提供了dart版,你想使用OKHttp发起http请求,那么你便可以通过适配器来无缝切换到OKHttp,而不用改之前的代码。

Dio 使用DefaultHttpClientAdapter作为其默认HttpClientAdapter,DefaultHttpClientAdapter使用dart:io:HttpClient 来发起网络请求。

这里 有一个简单的自定义Adapter的示例,读者可以参考。另外本项目的自动化测试用例全都是通过一个自定义的MockAdapter来模拟服务器返回数据的。

Options

Options对象包含了对网络请求的配置,在1.x中无论是实例配置还是单次请求的配置都使用的是Options 对象,这样会带来一些二义性,甚至有时会让开发者感到疑惑,比如Options.baseUrl属性代表请求基地址,理论上它只应该在实例配置中设置,而不应该出现在每次请求的配置中;再比如Options.path属性,它代表请求的相对路径,不应该在实例请求配置中。2.1中将请求配置分拆成三个类:

类名 作用
BaseOptions Dio实例基配置,默认对该dio实例的所有请求生效
Options 单次请求配置,可以覆盖BaseOptions中的同名属性
RequestOptions 请求的最终配置,是对Option和BaseOptions合并后的

另外,添加了一些新的配置项:

  1. cookies:可以添加一些公共cookie
  2. receiveDataWhenStatusError:当响应状态码不是成功状态(如404)时,是否接收响应内容,如果是false,则response.data将会为null
  3. maxRedirects: 重定向最大次数。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • 《随园拍诗——拍的就是你》的初衷是通过对大家的作品的尖锐点评,把各位原先隐藏的缺点全部揭露出来,并加以改进,使大家...
    霙愔阅读 551评论 1 3
  • 今早去餐饮部吃饭,饭毕,恰逢服务员大姐在旁边收拾桌子,我就习惯性的把碗筷拿起来,放到了她的小推车里面,本是稀松平常...
    归园田居其一阅读 335评论 8 6
  • 我儿胖,特别费衣裤。尤其是裤裆,新裤子有时候不出一周就磨破了裤裆。扔了多可惜啊,逼我手拿针线补裤裆。 有时候,恨不...
    蔷薇季阅读 353评论 0 0
  • 知乎上有一个问题,坚持长时间做一件事是什么体验,下面回答的总结起来分布在健身、早起、读书、练字,也许是我的...
    糖糖风阅读 165评论 0 0