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: 重定向最大次數。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 《隨園拍詩——拍的就是你》的初衷是通過對大家的作品的尖銳點評,把各位原先隱藏的缺點全部揭露出來,并加以改進,使大家...
    霙愔閱讀 605評論 1 3
  • 今早去餐飲部吃飯,飯畢,恰逢服務員大姐在旁邊收拾桌子,我就習慣性的把碗筷拿起來,放到了她的小推車里面,本是稀松平常...
    歸園田居其一閱讀 356評論 8 6
  • 我兒胖,特別費衣褲。尤其是褲襠,新褲子有時候不出一周就磨破了褲襠。扔了多可惜啊,逼我手拿針線補褲襠。 有時候,恨不...
    薔薇季閱讀 398評論 0 0
  • 知乎上有一個問題,堅持長時間做一件事是什么體驗,下面回答的總結起來分布在健身、早起、讀書、練字,也許是我的...
    糖糖風閱讀 178評論 0 0