Flutter 网络请求之dio三方库(建议使用)

6,867 阅读2分钟

和谐学习!不急不躁!!我是你们的老朋友小青龙~

前言

前面,我们讲到了Flutter常用的「网络请求库」有httpdio

而http的使用,也已经在开头的链接文章里给出来了,本文就以下内容进行讲解:

  • dio的使用

  • 针对dio库的「网络请求的封装」

dio的使用

1、打开第三方开源库

2、搜索dio

image.png

3、复制版本号

image.png

4、打开pubspec.yaml进行配置

image.png

5、点击按钮加载第三方库

image.png

6、来到需要发起请求的地方

import 'package:dio/dio.dart';

void main() {
  getHttp();
}

void getHttp() async {
  try {
    var response = await Dio()
        .get('http://rap2api.taobao.org/app/mock/293606/api/chat/list');
    print('打印结果:$response');
  } catch (e) {
    print('异常信息:$e');
  }
}

7、运行结果

image.png

封装网络请求 「dio」库

创建请求管理类 - SSJRequestManager

新建dart文件:ssj_request_manager.dart

内容如下:

import 'package:dio/dio.dart';

// 枚举类型 - 请求类型
enum HttpType { HttpTypeGet, HttpTypePost }

class SSJRequestManager {
  // 单例方法
  static Dio? _dioInstance;
  static Dio getSSJRequestManager() {
    if (_dioInstance == null) {
      _dioInstance = Dio();
    }
    return _dioInstance!;
  }

  // 对外抛出方法 - get请求
  static Future<Response> get(String requestUrl) async {
    return await _sendHttpRequest(HttpType.HttpTypeGet, requestUrl);
  }

  // 对外抛出方法 - post请求
  static Future<Response> post(String requestUrl,
      {Map<String, dynamic>? queryParameters}) async {
    return await _sendHttpRequest(HttpType.HttpTypePost, requestUrl,
        queryParameters: queryParameters);
  }

  // 私有方法 - 处理get请求、post请求
  static Future _sendHttpRequest(HttpType type, String requestUrl,
      {Map<String, dynamic>? queryParameters, dynamic data}) async {
    try {
      switch (type) {
        case HttpType.HttpTypeGet:
          return await getSSJRequestManager().get(requestUrl);
        case HttpType.HttpTypePost:
          return await await getSSJRequestManager()
              .post(requestUrl, queryParameters: queryParameters, data: data);
        default:
          throw Exception('报错了:请求只支持get和post');
      }
    } on DioError catch (e) {
      print("报错:$e");
    }
  }

  // 对外抛出方法 - 下载文件
  static void downloadFile(String downLoadUrl, String savePath,
      void Function(bool result) func) async {
    DateTime timeStart = DateTime.now();
    print('开始下载~当前时间:$timeStart');
    try {
      Dio dio = getSSJRequestManager();
      var response = await dio.download(downLoadUrl, savePath,
          onReceiveProgress: (int count, int total) {
        String progressValue = (count / total * 100).toStringAsFixed(1);
        print('当前下载进度:$progressValue%');
      }).whenComplete(() {
        DateTime timeEnd = DateTime.now();
        //用时多少秒
        int second_use = timeEnd.difference(timeStart).inSeconds;
        print('下载文件耗时$second_use秒');
        func(true);
      });
    } catch (e) {
      print("downloadFile报错:$e");
    }
  }
}

案例 - 下载文件

下载文件 - 到Mac电脑桌面
import 'package:flutter_async_programming/tools/ssj_request_manager.dart';

void main() {
  String savePath = "/Users/jss/Desktop/downloadFiles/微信.dmg";
  String downLoadUrl =
      "https://edu-files-1251502357.cos.ap-shanghai.myqcloud.com/CourseTeacher_2.8.1.13_DailyBuild.dmg";

  SSJRequestManager.downloadFile(downLoadUrl, savePath, (result) {
    if (result) {
      print("下载成功");
    } else {
      print("下载失败");
    }
  });
}

运行效果

image.png

下载文件 - 到iPhone真机

需要先加载一个三方库:path_provider

image.png

path_provider插件是用来获取各种目录的。

具体代码如下

import 'package:flutter/material.dart';
import 'package:flutter_async_programming/tools/ssj_request_manager.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  downLoadMethod();
}

/// 下载
void downLoadMethod() {
  _localFile.then((savePath) {
    print('下载路径:$savePath');

    String downLoadUrl =
        "https://edu-files-1251502357.cos.ap-shanghai.myqcloud.com/CourseTeacher_2.8.1.13_DailyBuild.dmg";

    SSJRequestManager.downloadFile(downLoadUrl, savePath, (result) {
      if (result) {
        print("下载成功");
      } else {
        print("下载失败");
      }
    });
  });
}

/// 获得沙盒文件夹目录
Future<String> get _localPath async {
  WidgetsFlutterBinding.ensureInitialized(); //解决加载json错误
  final directory = await getApplicationDocumentsDirectory();
  return directory.path;
}

/// 拼接具体文件路径
Future<String> get _localFile async {
  final path = await _localPath;
  // return File('$path/counter.txt');
  // return File('$path/downloadFiles/微信.dmg');
  return '$path/downloadFiles/微信.dmg';
}

运行效果:

image.png

image.png

然后把手机上的app文件目录下载到本地,并且右键显示包内容

image.png

然后我们发现了刚刚下载的文件微信.dmg

image.png

说明在iOS真机上是可以的

安卓的真机测试环境,目前还没有,所以这个需要小伙伴自行去测试。

案例 - get请求

import 'package:flutter_async_programming/tools/ssj_request_manager.dart';

void main() {
  // get请求
  String urlString = "http://rap2api.taobao.org/app/mock/293606/api/chat/list";
  SSJRequestManager.get(urlString).then((value) {
    print('\n\n2222请求返回:$value');
  });
}

运行效果

image.png

post请求,由于暂时没有相关测试条件,这里就先不测试了,小伙伴们可以自行测试。

补充

没有完全适用的封装库,因为dio的拓展方法有点多,没有必要把所有的方法都暴露给外界。所以小伙伴们可以酌情处理。

path_provider介绍

参详情参考文章:blog.csdn.net/m0_52390420…

path_provider插件是用来获取各种目录的。

其它方法使用:

  • getTemporaryDirectory() :获取临时文件路径(IOS和安卓通用)

  • getApplicationSupportDirectory() :获取应用支持目录(IOS和安卓通用)

  • getApplicationDocumentsDirectory() :获取应用文件目录(IOS和安卓通用),针对 Android 设备的 AppDate 目录,iOS 设备的 NSDocumentDirectory 目录

  • getLibraryDirectory() :获取应用持久存储目录路径(仅IOS可用)

  • getExternalStorageDirectory() : 获取存储卡目录(仅安卓可用)

  • getExternalCacheDirectories() :获取外部缓存目录(仅安卓可用)

  • getDownloadsDirectory() :获取下载目录(仅桌面可用)