跟我學企業級flutter專案:dio網路框架增加公共請求引數&header

語言: CN / TW / HK

前言

在開發過程中,我們經常會用到網路請求,在flutter框架中,dio框架非常不錯,所以今天的文章在dio的基礎上搭建一套網路持久化框架,那麼在flutter專案中如何搭建一套,高可用性,維護性較高的dio公共請求引數框架呢?

搭建前夕準備

一、基本認知

  1. 要持久化那麼必然要有儲存裝置
  2. 持久化的資料在app啟動後要即使填充到專案中
  3. 由於專案中網路請求地址繁多,型別不同,需要持久化的位置不同

二、基於基本認知來找合適的工具&必要點

2.1 持久化的工具:

我的推薦 1. mmkv 2. share_prefresence

今天主要用講解mmkv版本

2.2必要點:

dio攔截器

攔截器是搭建這套持久化的關鍵

三、準備好如上技能,我們來搭建這套持久化網路框架吧

1、首先要知道有幾種型別的公共 bash //請求中url後追加公共請求 static const int urlPresistent = 1; //請求頭中追加公共請求 static const int headerPresistent = 2; //全部都追加公共請求 static const int allPresistent = 3;

2、構建快取引數(為了快速獲取)

bash static Map<String,Map<String, String?>> headerPersistent = Map(); static Map<String,Map<String, String?>> urlPersistent = Map();

3、構建mmkv儲存結構(加密儲存)

bash static MMKV _store(String baseUrl, int type) => MMKVStore.sysSafeMMKV(name: '${SysConfig.sysPersistent}${baseUrl}_${type.toString()}'); 4、構建基本函式

單健值對儲存 bash static void setPersistent(String baseUrl,String key,String? value,{int type = allPresistent}){ if (type == allPresistent || type == headerPresistent) { if (!headerPersistent.containsKey(baseUrl)) { headerPersistent[baseUrl] = Map<String, String?>(); } var keyMap = headerPersistent[baseUrl]!; keyMap[key] = value; _store(baseUrl, headerPresistent).encodeString(key, value??""); } if (type == allPresistent || type == urlPresistent) { if (!urlPersistent.containsKey(baseUrl)) { urlPersistent[baseUrl] = Map<String, String?>(); } var keyMap = urlPersistent[baseUrl]!; keyMap[key] = value; _store(baseUrl, urlPresistent).encodeString(key, value??""); } }

多健值對儲存

bash static void setPersistentMap(String baseUrl,Map<String, String?> map,{int type = allPresistent}){ if (type == allPresistent || type == headerPresistent) { if (!headerPersistent.containsKey(baseUrl)) { headerPersistent[baseUrl] = Map<String, String?>(); } var keyMap = headerPersistent[baseUrl]!; keyMap.addAll(map); keyMap.forEach((key, value) { _store(baseUrl, headerPresistent).encodeString(key, value??""); }); } if (type == allPresistent || type == urlPresistent) { if (!urlPersistent.containsKey(baseUrl)) { urlPersistent[baseUrl] = Map<String, String?>(); } var keyMap = urlPersistent[baseUrl]!; keyMap.addAll(map); keyMap.forEach((key, value) { _store(baseUrl, urlPresistent).encodeString(key, value??""); }); } }

引數獲取:

```bash static Map? getPersistent(String baseUrl, {int type = allPresistent}) { Map? map; if (type == allPresistent || type == headerPresistent) { Map? headerMap; if (headerPersistent.containsKey(baseUrl)) { headerMap = headerPersistent[baseUrl]; } else { headerMap = null; } if (headerMap != null) { if (map == null) { map = Map(); } map.addAll(headerMap); } } if (type == allPresistent || type == urlPresistent) { Map? urlMap; if (urlPersistent.containsKey(baseUrl)) { urlMap = urlPersistent[baseUrl]; } else { urlMap = null; }

  if (urlMap != null) {
    if (map == null) {
      map = Map();
    }
    map.addAll(urlMap);
  }
}
return map;

} ```

重新整理當前快取(應用啟動重新整理) ```bash static Map _all(String baseurl, int type) { var mmkv= _store(baseurl, type); var keys = mmkv.allKeys; var map = Map(); keys.forEach((element) { var value = mmkv.decodeString(element); map[element] = value; }); return map; }

static void flushPersistent(String baseurl, {int type = allPresistent}) { if (type == allPresistent || type == headerPresistent) { var map = _all(baseurl, headerPresistent); headerPersistent[baseurl]?.clear();

  if (!headerPersistent.containsKey(baseurl)) {
    headerPersistent[baseurl] = Map<String, String?>();
  }
  var keyMap = headerPersistent[baseurl]!;
  keyMap.addAll(map);
}
if (type == allPresistent || type == urlPresistent) {
  var map = _all(baseurl, urlPresistent);
  urlPersistent[baseurl]?.clear();
  if (!urlPersistent.containsKey(baseurl)) {
    urlPersistent[baseurl] = Map<String, String?>();
  }
  var keyMap = urlPersistent[baseurl]!;
  keyMap.addAll(map);
}

} ```

退出登陸移除持久化 bash static void removeAllPersistent(String baseurl, {int type = allPresistent}) { if (type == allPresistent || type == headerPresistent) { headerPersistent[baseurl]?.clear(); _store(baseurl, headerPresistent).clearAll(); } if (type == allPresistent || type == urlPresistent) { urlPersistent[baseurl]?.clear(); _store(baseurl, urlPresistent).clearAll(); } }

攔截器實現(dio請求攔截管理)

```bash class PresistentInterceptor extends Interceptor {

@override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { var urlPersitents = HttpPersistent.getPersistent(options.baseUrl,type: HttpPersistent.urlPresistent); var headerPersitents = HttpPersistent.getPersistent(options.baseUrl, type: HttpPersistent.headerPresistent); headerPersitents?.forEach((key, value) { options.headers[key] = value; });

urlPersitents?.forEach((key, value) {
  options.queryParameters[key] = value;
});
super.onRequest(options, handler);

}

} ```

四、整體程式碼&事件呼叫邏輯

整體程式碼 ```bash

class HttpPersistent{

static const int urlPresistent = 1; static const int headerPresistent = 2; static const int allPresistent = 3;

static MMKV store(String baseUrl, int type) => MMKVStore.sysSafeMMKV(name: '${SysConfig.sysPersistent}${baseUrl}${type.toString()}'); static Map> headerPersistent = Map(); static Map> urlPersistent = Map();

static void setPersistent(String baseUrl,String key,String? value,{int type = allPresistent}){ if (type == allPresistent || type == headerPresistent) { if (!headerPersistent.containsKey(baseUrl)) { headerPersistent[baseUrl] = Map(); } var keyMap = headerPersistent[baseUrl]!; keyMap[key] = value; _store(baseUrl, headerPresistent).encodeString(key, value??""); } if (type == allPresistent || type == urlPresistent) { if (!urlPersistent.containsKey(baseUrl)) { urlPersistent[baseUrl] = Map(); } var keyMap = urlPersistent[baseUrl]!; keyMap[key] = value; _store(baseUrl, urlPresistent).encodeString(key, value??""); } }

static void setPersistentMap(String baseUrl,Map map,{int type = allPresistent}){ if (type == allPresistent || type == headerPresistent) { if (!headerPersistent.containsKey(baseUrl)) { headerPersistent[baseUrl] = Map(); } var keyMap = headerPersistent[baseUrl]!; keyMap.addAll(map); keyMap.forEach((key, value) { _store(baseUrl, headerPresistent).encodeString(key, value??""); }); } if (type == allPresistent || type == urlPresistent) { if (!urlPersistent.containsKey(baseUrl)) { urlPersistent[baseUrl] = Map(); } var keyMap = urlPersistent[baseUrl]!; keyMap.addAll(map); keyMap.forEach((key, value) { _store(baseUrl, urlPresistent).encodeString(key, value??""); }); } }

static Map? getPersistent(String baseUrl, {int type = allPresistent}) { Map? map; if (type == allPresistent || type == headerPresistent) { Map? headerMap; if (headerPersistent.containsKey(baseUrl)) { headerMap = headerPersistent[baseUrl]; } else { headerMap = null; } if (headerMap != null) { if (map == null) { map = Map(); } map.addAll(headerMap); } } if (type == allPresistent || type == urlPresistent) { Map? urlMap; if (urlPersistent.containsKey(baseUrl)) { urlMap = urlPersistent[baseUrl]; } else { urlMap = null; }

  if (urlMap != null) {
    if (map == null) {
      map = Map();
    }
    map.addAll(urlMap);
  }
}
return map;

}

static Map _all(String baseurl, int type) { var mmkv= _store(baseurl, type); var keys = mmkv.allKeys; var map = Map(); keys.forEach((element) { var value = mmkv.decodeString(element); map[element] = value; }); return map; }

static void flushPersistent(String baseurl, {int type = allPresistent}) { if (type == allPresistent || type == headerPresistent) { var map = _all(baseurl, headerPresistent); headerPersistent[baseurl]?.clear();

  if (!headerPersistent.containsKey(baseurl)) {
    headerPersistent[baseurl] = Map<String, String?>();
  }
  var keyMap = headerPersistent[baseurl]!;
  keyMap.addAll(map);
}
if (type == allPresistent || type == urlPresistent) {
  var map = _all(baseurl, urlPresistent);
  urlPersistent[baseurl]?.clear();
  if (!urlPersistent.containsKey(baseurl)) {
    urlPersistent[baseurl] = Map<String, String?>();
  }
  var keyMap = urlPersistent[baseurl]!;
  keyMap.addAll(map);
}

}

static void removeAllPersistent(String baseurl, {int type = allPresistent}) { if (type == allPresistent || type == headerPresistent) { headerPersistent[baseurl]?.clear(); _store(baseurl, headerPresistent).clearAll(); } if (type == allPresistent || type == urlPresistent) { urlPersistent[baseurl]?.clear(); _store(baseurl, urlPresistent).clearAll(); } } }

class PresistentInterceptor extends Interceptor {

@override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { var urlPersitents = HttpPersistent.getPersistent(options.baseUrl,type: HttpPersistent.urlPresistent); var headerPersitents = HttpPersistent.getPersistent(options.baseUrl, type: HttpPersistent.headerPresistent); headerPersitents?.forEach((key, value) { options.headers[key] = value; });

urlPersitents?.forEach((key, value) {
  options.queryParameters[key] = value;
});
super.onRequest(options, handler);

}

} ```

1、登陸後,呼叫儲存 HttpPersistent.setPersistent("http://www.baidu.com","token","123",HttpPersistent.headerPresistent)

2、退出登陸後,呼叫移除 HttpPersistent.removeAllPersistent("http://www.baidu.com",,type: HttpPersistent.headerPresistent);

3、應用啟動後重新整理快取
HttpPersistent.flushPersistent("http://www.baidu.com", type: HttpPersistent.headerPresistent);

五、大功告成

如上就構建出一套可靠性高,維護性高的網路持久化框架

更多flutter教程請關注我的IMGeek:https://www.imgeek.org/people/33692