前言
本文讲的是使用flutter时,如何使用dio进行网络层封装的解决方案。
相关链接
1). flutter
2). dio
进入正题
安装dio
打开pubspec.yaml
文件,导入dio
包,并安装依赖,代码如下:
1 | dev_dependencies: |
2 | flutter_test: |
3 | sdk: flutter |
4 | dio: ^3.0.9 |
具体实现
接下来是具体的实现步骤,先上一个目录图
新建目录
config
,新建文件config.dart
,定义ENV
基类,代码如下:1
import 'package:flutter/material.dart';
2
3
class ENV extends InheritedWidget {
4
static String appName; // 系统名称
5
static String envName; // 运行环境
6
static String baseUrl; // 基础url
7
8
ENV({
9
String appName,
10
String envName,
11
String baseUrl,
12
Widget child,
13
}) : super(child: child){
14
ENV.appName = appName;
15
ENV.envName = envName;
16
ENV.baseUrl = baseUrl;
17
}
18
19
static ENV of(BuildContext context) {
20
return context.dependOnInheritedWidgetOfExactType(aspect: ENV);
21
}
22
23
24
bool updateShouldNotify(InheritedWidget oldWidget) => false;
25
}
分离构建环境,区分
dev
和prod
环境。新建dev.dart
以及prod.dart
,分别作为开发环境以及生产环境的构建脚本。代码如下:1
// dev.dart
2
import 'package:flutterfluro/main.dart';
3
import 'package:flutter/material.dart';
4
import 'package:flutterfluro/config/config.dart';
5
6
void main() {
7
var configuredApp = new ENV(
8
appName: 'flutter_fluro_dev',
9
envName: 'dev',
10
baseUrl: 'http://127.0.0.1:9991/v1',
11
child: new MyApp(),
12
);
13
runApp(configuredApp);
14
}
1 | // prod.dart |
2 | import 'package:flutter/material.dart'; |
3 | import 'package:flutterfluro/main.dart'; |
4 | import 'package:flutterfluro/config/config.dart'; |
5 | |
6 | void main() { |
7 | var configuredApp = new ENV( |
8 | appName: 'flutter_fluro_prod', |
9 | envName: 'prod', |
10 | baseUrl: 'http://127.0.0.1:8888/v1', |
11 | child: new MyHomePage(), |
12 | ); |
13 | runApp(configuredApp); |
14 | } |
配置构建环境启动方式,如下图:
新建文件
http.dart
,封装网络层,代码如下:
1 | import 'package:dio/dio.dart'; |
2 | import 'package:flutterfluro/config/config.dart'; // `flutterfluro`替换为自己对应的目录名 |
3 | |
4 | final dio = Dio(BaseOptions( |
5 | baseUrl: ENV.baseUrl, |
6 | connectTimeout: 5000, |
7 | receiveTimeout: 100000, |
8 | contentType:"application/json; charset=utf-8", |
9 | )); |
10 | |
11 | Future main({String url = '', String type = 'get', Map<String,dynamic>data}) async { |
12 | type = type.toUpperCase(); |
13 | if(data != null) { |
14 | data.containsKey('id') ? url = url + '/' + data['id'] : url = url; |
15 | } |
16 | print('请求参数: url: $url, type: $type, data: $data'); |
17 | |
18 | if (type == 'POST') { |
19 | Response response; |
20 | await dio.post(url, data: data).then((res) { |
21 | response = res; |
22 | }).catchError((err) => throw Exception('$url: $err')); |
23 | return response.data; |
24 | } |
25 | |
26 | if (type == 'GET'){ |
27 | List getParams = []; |
28 | |
29 | if (data != null && data.containsKey('params')) { |
30 | data['params'].forEach((k, v)=> getParams.add("$k=$v")); |
31 | String str = getParams.join('&'); |
32 | url += '?' + str; |
33 | } |
34 | Response response; |
35 | await dio.get(url).then((res) { |
36 | response = res; |
37 | }).catchError((err) => throw Exception('$url: $err')); |
38 | return response.data; |
39 | } |
40 | |
41 | if(type == 'PUT') { |
42 | Response response; |
43 | await dio.put(url, data:data).then((res) { |
44 | response = res; |
45 | }).catchError((err) => throw Exception('$url: $err')); |
46 | return response.data; |
47 | } |
48 | |
49 | if (type == 'DELETE') { |
50 | Response response; |
51 | await dio.delete(url, data:data).then((res) { |
52 | response = res; |
53 | }).catchError((err) => throw Exception('$url: $err')); |
54 | return response.data; |
55 | } |
56 | } |
新建目录
api
,新建文件interface.dart
,定义对应的网络请求。代码如下:1
import 'package:flutterfluro/config/http.dart';
2
3
class Fetch {
4
static getArticle(params)=> main(url: '/article', type: 'get', data: params);
5
}
新建目录
pages
,新建index.dart
,作为应用的主页面,代码如下:1
import 'package:flutter/material.dart';
2
import 'package:flutterfluro/config/config.dart';
3
import 'package:flutterfluro/api/interface.dart';
4
5
class MyHomePage extends StatefulWidget {
6
7
_MyHomePageState createState() => new _MyHomePageState();
8
}
9
10
class _MyHomePageState extends State<MyHomePage> {
11
12
Object data;
13
14
void initState() {
15
super.initState();
16
loadData();
17
}
18
19
20
Widget build(BuildContext context) {
21
return Scaffold(
22
appBar: AppBar(
23
title: Text(ENV.appName),
24
),
25
body: Center(
26
child: Column(
27
mainAxisAlignment: MainAxisAlignment.start,
28
children: <Widget>[
29
Text('app name: ${ENV.envName}.'),
30
Text('env url: ${ENV.baseUrl}.'),
31
Text('env data: $data'),
32
],
33
),
34
),
35
);
36
}
37
38
void loadData() async{
39
Map article = await Fetch.getArticle({ 'id': '1'});
40
data = article;
41
}
42
}
修改
main.dart
,引用index.dart
。代码如下:1
import 'package:flutter/material.dart';
2
import 'package:flutterfluro/pages/index.dart';
3
import 'package:flutterfluro/config/config.dart';
4
5
class MyApp extends StatelessWidget {
6
7
Widget build(BuildContext context) {
8
return new MaterialApp(
9
title: ENV.appName,
10
theme: new ThemeData(
11
primarySwatch: Colors.blue,
12
),
13
home: new MyHomePage(),
14
);
15
}
16
}
启动服务,效果如下图: