Flutter學(xué)習(xí)整理(一)

Flutter開發(fā)對(duì)于Http對(duì)于網(wǎng)絡(luò)請(qǐng)求的封裝及Json數(shù)據(jù)處理

logo.jpeg

目錄

Flutter學(xué)習(xí)整理(二)

前言

????自谷歌在2018大會(huì)公布Beta1也有了一段時(shí)間,這段時(shí)間以來(lái)flutter也越來(lái)越熱。這段時(shí)間我也對(duì)Flutter進(jìn)行了一些學(xué)習(xí),今天準(zhǔn)備把一些學(xué)的內(nèi)容進(jìn)行整理,一是為了梳理下學(xué)習(xí)的一些知識(shí)節(jié)點(diǎn),二是通過一些封裝整理,方便后期如過需要使用flutter開發(fā)可以快速搭建基礎(chǔ)組件進(jìn)行開發(fā)。

目錄結(jié)構(gòu)

15585042055957.jpg

對(duì)于項(xiàng)目,我做了如上一些目錄區(qū)分:
dao:主要做一些接口調(diào)用及邏輯處理。
exts:做一些擴(kuò)展累比如callback等。
http:對(duì)網(wǎng)絡(luò)請(qǐng)求dio的再次封裝。
json:對(duì)數(shù)據(jù)json解析接口定義。
model:對(duì)bean類的定義。
viewmodel:對(duì)頁(yè)面數(shù)據(jù)集合類。

這篇文章中,主要是對(duì)http和json解析兩塊的封裝使用。

HTTP

Dio

????dio作為一個(gè)強(qiáng)大的Drat Http開源請(qǐng)求庫(kù),我們已經(jīng)可以很方便的使用它進(jìn)行一些網(wǎng)絡(luò)請(qǐng)求,但我對(duì)它進(jìn)行了二次封裝,主要是一些配置的統(tǒng)一設(shè)置和一些邏輯的統(tǒng)一處理。

15585068875920.jpg

????我們先來(lái)看DioUtil類,這里我采用單例模式來(lái)創(chuàng)建dio對(duì)象,并默認(rèn)設(shè)置了baseurl,也可以在項(xiàng)目啟動(dòng)使用通過init()方法設(shè)置Options來(lái)初始化配置。

http

15585079511513.jpg

????在HttpUtil中最主要是對(duì)dio的request()方法進(jìn)行封裝,提供了統(tǒng)一的配置和處理。
其中:

 //可以通過mheaders配置公共head
    mheaders = new Map<String, dynamic>();
    if (handers != null) {
      mheaders.addAll(handers);
    }
    options.headers = mheaders;

????可以通過mheaders配置統(tǒng)一的head及組合由方法傳入的handers組成最終的請(qǐng)求head。

static String errorNet = "{\"code\":19,\"msg\":\"網(wǎng)絡(luò)錯(cuò)誤,請(qǐng)檢查網(wǎng)絡(luò)情況\"}";

ConnectUtil.isConnect((val) async {
    if (val) {
        ...
   } else {
        callback(19, errorNet);
      } 
}

????在真正請(qǐng)求開始前通過ConnectUtil做網(wǎng)絡(luò)情況判斷,因?yàn)楫惒剑酝ㄟ^回調(diào)方式處理并做預(yù)定格式返回錯(cuò)誤。(網(wǎng)絡(luò)情況判斷通過第三方connectivity框架實(shí)現(xiàn))

static String errorMsg = "{\"code\":0,\"msg\":\"數(shù)據(jù)訪問錯(cuò)誤,請(qǐng)檢查\"}";

final code = response.statusCode;
          final strJson = response.data.toString();
          LogUtil.d("HttpUtil", "code:" + code.toString() + " outdata:" + data);
          if (strJson != null && strJson != "") {
            if (code != 200) {
              callback(0, errorMsg);
            } else {
              callback(code, strJson);
            }
          } else {
            callback(0, errorMsg);
          }

????請(qǐng)求返回后,如果請(qǐng)求錯(cuò)誤,也同樣做了統(tǒng)一的錯(cuò)誤格式返回,同時(shí)也可以在這里做統(tǒng)一的錯(cuò)誤邏輯處理。

15585091230552.jpg

????同時(shí)HttpUtil提供get和post兩個(gè)簡(jiǎn)單的api進(jìn)行及少量入?yún)⒓纯蛇M(jìn)行網(wǎng)絡(luò)請(qǐng)求。

JSON

????因?yàn)镕lutter中是禁止反射的,所為我們也就不能使用GSON / Jackson之類的進(jìn)行序列化和反序列化。然而我們現(xiàn)在很多時(shí)間接口請(qǐng)求都是以json格式進(jìn)行返回的。那么又怎么樣實(shí)現(xiàn)從json到model到轉(zhuǎn)換呢。
????在項(xiàng)目中我通過我通過dart:convert中內(nèi)置的JSON解碼器,它將原始JSON字符串傳遞給JSON.decode() 方法,然后在返回的Map<String, dynamic>中查找所需的值,通過手動(dòng)的方式進(jìn)行實(shí)現(xiàn)。

15585105639025.jpg

????首先通過JsonModel設(shè)置抽象方法bind(),然后讓所有model類都繼承JsonModel類并實(shí)現(xiàn)bind()方法,并且bing方法的參數(shù)為Map類型,所以每個(gè)model方法只需先實(shí)現(xiàn)中通過map獲取所需的屬性值即可。如下面UserModel類所示。


15585107540593.jpg

????那我們又在什么時(shí)候吧json轉(zhuǎn)換成map的呢?入下圖,我創(chuàng)建了JsonViewModel類來(lái)進(jìn)行此項(xiàng)操作。


15585110228177.jpg

15585115237214.jpg

????在JsonViewModel中通過fromJson()方法傳入json字符串,然后通過json.decode(data)方法解析成map。
????因?yàn)镴sonViewModel也同樣繼承了JsonModel。所以我們可以bind(jMap["data"]);的形式調(diào)研bind方法并傳入對(duì)于數(shù)據(jù),并且在JsonViewModel的子類中做具體處理。
????要注意的是,我們預(yù)先把返回的json格式定義成了code,msg,data的形式,如果預(yù)定義的返回格式有修改可以在這邊進(jìn)行調(diào)整。

15585116032962.jpg

????至此,我們只需要在請(qǐng)求返回時(shí)候?qū)嵗瘜?duì)應(yīng)的viewmodel類,并調(diào)用fromJson()方法就可以得到對(duì)于的數(shù)據(jù)實(shí)體了。

GitHub

要看源碼點(diǎn)這里

大家要是看了覺得還可以,點(diǎn)個(gè)贊給個(gè)支持呀!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容