簡單6步搞定Flutter網路請求

CoorChice發表於2019-04-15

目錄傳送門:《Flutter快速上手指南》先導篇

在 Flutter 中,可以使用 dart:io 包裡提供的原生的 HttpClient 來構建網路請求。

1.HttpClient 使用步驟

首先,需要匯入以下兩個 dart 包:

import 'dart:convert';
import 'dart:io';
複製程式碼
  1. 建立 HttpClient

    HttpClient httpClient = HttpClient();
    複製程式碼
  2. 構建請求 uri

    var uri = new Uri.http('v.juhe.cn', '/toutiao/index',
            {'key': '******', 'type': 'keji'});
    複製程式碼
  3. 開啟Http連線

    var request = await httpClient.getUrl(uri);
    複製程式碼
  4. 等待連線伺服器(會將請求資訊傳送給伺服器),請求成功後會返回 HttpClientResponse

    var response = await request.close();
    複製程式碼
  5. 讀取響應內容

    // 判斷 response 狀態
    if (response.statusCode == HttpStatus.ok) {
      // 轉換 response,獲取結果
      var responseBody = await response.transform(utf8.decoder).join();
    } 
    複製程式碼
  6. 關閉client,通過該client發起的所有請求都會中止

    httpClient.close();
    複製程式碼

2. 一種資料解析的方案

Flutter 禁止了 dart 中的反射!

這可能讓你請求到資料後,解析成資料類變得困難重重...

畢竟,在 Java 中的 Json 解析庫 Gson、FastJson 等內部,都依賴於反射實現。

當然, 官方推薦的方案 也不是不能用,但使用起來,實在費勁。

現在,推薦一種解析資料的方案。

在開始瞭解這種方案前,建議先看一下章節: 資料類,瞭解如何不費吹灰之力的生成 Json 可轉的資料類。

首先,在我們的專案中,介面返回的資料通常是約定好了一個最基礎的結構的,比如:

這樣的

{
    "reason": "成功的返回",
    "result": {
        "stat": "1",
        "data": ...
    },
    "error_code": 0
}
複製程式碼

或者這樣的

{
    "reason": "成功的返回",
    "data":...,
    "error_code": 0
}
複製程式碼

其中,除了 data 部分是變化的,其餘部分都是固定的格式。

我們通常會封裝一個基礎的資料類,然後讓 data 部分成為動態的(比如使用一個範型來代替佔位),因為我們不想重複的定義這種結構的資料類。

以第一種結構為例,看看如何實現吧。

  1. 定義基礎資料類 Response

    import 'dart:convert';
    
    class Response{
      String reason;
      int error_code;
      Result result;
    
      // parseDataFunction data 資料類的解析函式
      static Response parse(String data, var parseDataFunction) {
        // 通過 dart:convert 提供的 jsonDecode() 函式將原始資料類轉換為 Map<String, dynamic> map
        var map = jsonDecode(data);
        Response response = Response();
        response.reason = map['reason'];
        response.error_code = map['error_code'];
        response.result = Result.fromMap(map['result'], parseDataFunction);
        return response;
      }
    }
    
    class Result{
      String stat;
      // 真正需要的資料類
      var data;
    
      static Result fromMap(Map<String, dynamic> map, var parseDataFunction){
        Result result = Result();
        result.stat = map['stat'];
        result.data = parseDataFunction(map['data']);
        return result;
      }
    }
    複製程式碼

    其中,核心有兩點:

    • 將動態的 data 定義為型別不定的變數就好,vardynamicObject 或者 範型 都可以。

    • 傳入 data 對應的資料類解析函式,這個外掛會自動生成。

  2. 使用外掛生成 data 部分的資料類

    參考章節: 資料類

  3. 使用

    • 解析普通資料類

      // 傳入 fromMap 函式
      Response responseData = Response.parse(responseBody, NewsData.fromMap);
      NewsData data = responseData.result.data;
      複製程式碼
    • 解析List型別的資料類

      // 傳入 List 的 fromMapList 函式
      Response responseData = Response.parse(responseBody, NewsData.fromMapList);
      List<NewsData> data = responseData.result.data;複製程式碼

目錄傳送門:《Flutter快速上手指南》先導篇

如何找到我?

傳送門:CoorChice 的主頁

傳送門:CoorChice 的 Github


相關文章