0%

flutter网络层封装解决方案

前言

本文讲的是使用flutter时,如何使用dio进行网络层封装的解决方案。

相关链接

1). flutter

2). dio

进入正题

安装dio

打开pubspec.yaml文件,导入dio包,并安装依赖,代码如下:

1
dev_dependencies:
2
  flutter_test:
3
    sdk: flutter
4
  dio: ^3.0.9
具体实现
  1. 接下来是具体的实现步骤,先上一个目录图

  2. 新建目录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
        @required String appName,
    10
        @required String envName,
    11
        @required String baseUrl,
    12
        @required 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
      @override
    24
      bool updateShouldNotify(InheritedWidget oldWidget) => false;
    25
    }
  3. 分离构建环境,区分devprod环境。新建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
}
  1. 配置构建环境启动方式,如下图:



  2. 新建文件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
}
  1. 新建目录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
    }
  2. 新建目录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
      @override
    7
      _MyHomePageState createState() => new _MyHomePageState();
    8
    }
    9
    10
    class _MyHomePageState extends State<MyHomePage> {
    11
    12
      Object data;
    13
      @override
    14
      void initState() {
    15
        super.initState();
    16
        loadData();
    17
      }
    18
    19
      @override
    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
    }
  3. 修改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
      @override
    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
    }
  4. 启动服务,效果如下图:

结语:关于flutter网络层封装的解决方案就介绍到这里了,下一篇文章是介绍flutter路由管理解决方案。