一、前言
最近學習Flutter進行到了網絡這一塊,所以就花了點時間對網絡請求進行了簡單的封裝,以便使用,網絡請求基于Dio,具體使用可自行學習。
二、結構
- net.dart 基于Dio封裝的get, post請求
- net_url.dart 對請求地址的統一管理
- net_util.dart 對net的二次封裝,將地址添加進來,統一管理網絡請求
image.png
三、代碼
- net.dart,代碼里都有注釋
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:demo/model/base_model.dart';
/// 自定義枚舉
enum Method {
get,
post
}
class Net{
// 工廠模式
factory Net() => _getInstance();
static Net get instance => _getInstance();
static Net _instance;
Dio dio;
Net._internal() {
// 初始化
dio = Dio(BaseOptions(
connectTimeout: 60000, // 連接服務器超時時間,單位是毫秒.
receiveTimeout: 10000, // 響應流上前后兩次接受到數據的間隔,單位為毫秒, 這并不是接收數據的總時限.
)
);
}
// 單列模式
static Net _getInstance() {
if (_instance == null){
_instance = Net._internal();
}
return _instance;
}
get(String url, Map<String,dynamic> params, {Function success,Function failure}){
_doRequest(url, params, Method.get, success, failure);
}
post(String url, Map<String,dynamic> params, {Function success,Function failure}){
_doRequest(url, params, Method.post, success, failure);
}
void _doRequest(String url, Map<String,dynamic> params ,Method method, Function successCallBack, Function failureCallBack) async{
try{
/// 可以添加header
// dio.options.headers.addAll({'token':xxx});
Response response;
switch (method){
case Method.get:
if (params != null && params.isNotEmpty){
response = await dio.get(url,queryParameters: params);
}else {
response = await dio.get(url);
}
break;
case Method.post:
if (params != null && params.isNotEmpty){
response = await dio.post(url,queryParameters: params);
}else {
response = await dio.post(url);
}
break;
}
Map<String, dynamic> result = json.decode(response.toString());
// 打印信息
print('''api: $url\nparams: $params\nresult: $result''');
// 轉化為model
BaseModel model = BaseModel.fromJson(result);
if (model.code == 200){ // 200 請求成功
if (successCallBack != null){//返回請求數據
successCallBack(model.data);
}
}else {
//TODO
//直接使用Toast彈出錯誤信息
//返回失敗信息
if (failureCallBack != null){
failureCallBack(model.error);
}
}
}catch (exception){
print('錯誤:${exception.toString()}');
Fluttertoast.showToast(msg: "請求失敗,請稍后再試");
if (failureCallBack != null){
failureCallBack(exception.toString());
}
}
}
// 上傳文件(圖片)
doUploadFile(String url, File file, String loadingText,Function successCallBack,
Function failureCallBack) async {
try {
String timeStamp = DateTime.now().millisecondsSinceEpoch.toString();
FormData formData = FormData.from({
'file': UploadFileInfo(file, '$timeStamp.jpg',
contentType: ContentType.parse("image/jpeg"))
});
Response response = await dio.post(url, data: formData);
print('$response'); // 在需要生成model時需要json格式
Map<String, dynamic> result = json.decode(response.toString());
assert(() {
// assert只會在debug模式下執行,release模式下不會執行
// 打印信息
print('''api: $url\nresult: $result''');
return true;
}());
BaseModel model = BaseModel.fromJson(result);
if (model.code == 200) {
// 200 請求成功
if (successCallBack != null) {
if (model.data != null) {
successCallBack(model.data);
} else {
successCallBack({});
}
}
} else {
//Fluttertoast.showToast(msg: "${model.msg}");
if (failureCallBack != null) {
failureCallBack(model.msg);
}
}
} catch (exception) {
assert(() {
// 打印信息
print('''api: $url\n錯誤:${exception.toString()}''');
return true;
}());
// Fluttertoast.showToast(msg: '加載失敗');
if (failureCallBack != null) {
failureCallBack(exception.toString());
}
}
}
}
- base_model.dart 上面使用到的model類
class BaseModel {
int code;
dynamic data;
String error;
BaseModel({this.code, this.data, this.error});
BaseModel.fromJson(Map<String, dynamic> json) {
code = json['code'];
data = json['data'];
error = json['error'];
}
}
- net_url.dart 請求地址
class NetUrl {
/// 服務器地址
static const String BASE_URL = "http://www.dio.com";
/// 登錄接口
static const String LOGIN_USER = BASE_URL + '/login';
}
- net_util.dart 請求的二次封裝,具體到某個請求,隱藏接口
import "net.dart";
import 'net_url.dart';
class NetUtil {
// 登錄
static void login(Map<String,dynamic> params,{Function success, Function failure}){
Net().post(NetUrl.LOGIN_USER, params,success: success, failure: failure);
}
}
4、具體使用
void requestData(){
var params = {'username':'xxx','password':'xxxx'};
NetUtil.login(params,success: (response){
},failure: (error){
});
}
5、總結
以上封裝還有幾點待完善
- 1、可以加上請求時的HUD,請求成功就消失掉
- 2、在net.dart,TODO的地方使用toast彈出錯誤信息,相當于將錯誤信息集中處理
至此網絡請求封裝與使用都完成了,有什么問題歡迎留言探討,如果對你有幫助或者你喜歡的話,給個贊吧??!