flutter开发实战-文件上传及上传队列

flutter开发实战-文件上传及上传队列

之前开发中遇到了发帖子图片上传,上传到七牛。

一、实现Dio上传

上传使用到Dio上传功能,具体代码

dart 复制代码
// 上传文件(图片)
  doUploadFile(String url, UploadFileInfo fileInfo,
      {Map<String, dynamic>? params,
      OnUploaded? uploaded,
      OnFailure? failure}) async {
    try {
      String timeStamp = DateTime.now().millisecondsSinceEpoch.toString();
      Map<String, dynamic> fromParams = Map();
      if (params != null && params.isNotEmpty) {
        fromParams.addAll(params);
      }

      fromParams["file"] = await MultipartFile.fromFile(fileInfo.file.path,
          filename: '${fileInfo.key}-${timeStamp}.jpg');

      FormData formData = FormData.fromMap(fromParams);
      Response? response = await dio.post(url, data: formData);
      assert(() {
        // assert只会在debug模式下执行,release模式下不会执行
        // 打印信息
        LoggerManager().error('''api: $url\nresult: $response''');
        return true;
      }());

      if (response != null) {
        Map<String, dynamic> result = json.decode(response.toString());
        assert(() {
          // assert只会在debug模式下执行,release模式下不会执行
          // 打印信息
          LoggerManager().debug('''api: $url\nresult: $result''');
          return true;
        }());

        if (response.statusCode == 200) {
          if (uploaded != null) {
            uploaded(result);
          }
        } else {
          //返回失败信息
          LoggerManager().error('''api: $url\nresult: $result''');

          ApiHttpError apiHttpError =
              ApiHttpError(ApiHttpErrorType.Default, "请求失败!");

          if (failure != null) {
            failure(apiHttpError);
          }
        }
      } else {
        //返回失败信息
        // 没有获得response,failure
        ApiHttpError apiHttpError =
            ApiHttpError(ApiHttpErrorType.Default, "请求失败!");

        if (failure != null) {
          failure(apiHttpError);
        }
      }
    } on DioError catch (e, s) {
      // catch到异常,failure
      LoggerManager().error("doUploadFile api: $url, dioError:$e, s:$s");
      ApiHttpError apiHttpError = getRequestFailure(e.response, e.type);

      if (failure != null) {
        failure(apiHttpError);
      }
    } catch (e) {
      // 可以捕获任意异常
      ApiHttpError apiHttpError =
          ApiHttpError(ApiHttpErrorType.Default, "${e.toString()}");

      if (failure != null) {
        failure(apiHttpError);
      }
    }
  }

二、实现上传到七牛uploader_tool

上传七牛需要获取上传七牛的token

dart 复制代码
void getQiniuToken(
      {required Function(String token) completion,
      required Function(ApiHttpError) failure}) {
    QiniuTokenRequest request = QiniuTokenRequest();
    GApiRepository.getQiniuToken(
      request: request,
      success: (response) async {
        Map<String, dynamic>? object = response.object;
        String token = "";
        if (object != null && object.isNotEmpty) {
          token = object["uptoken"];
        }

        if (completion != null) {
          completion(token);
        }
      },
      failure: (error) {
        if (failure != null) {
          failure(error);
        }
      },
    );
  }

调用doUploadFile实现上传

dart 复制代码
const String kQiniuUpHost = "http://up.qiniu.com";
const String kQiniuUndefinedKey = "?";
const String kQiniuUserAgent = "qiniu-ios-sdk";

const String kBucket = "bucket";
const String kQiniuDomainPreUrl = "domain";


void uploadImage(String imagePath, String token, {required Function(String key) completion,
    required Function(ApiHttpError) failure}) {
    String? key = StringUtils.toMD5(imagePath);
    String random = StringUtils.getRandom(10);
    String imageKey = "${key}-${random}";

    Map<String, dynamic> params = Map();
    params["bucket"] = "avatar";
    params["x:id"] = imageKey;
    params["token"] = token;
    params["User-Agent"] = kQiniuUserAgent;

    UploadFileInfo fileInfo =
    UploadFileInfo(file: File(imagePath), key: imageKey);

    HttpApi().doUploadFile(
      kQiniuUpHost,
      fileInfo,
      params: params,
      uploaded: (Map<String, dynamic> result) {
        String? aResultKey = result["key"];
        completion(aResultKey ?? "");
      },
      failure: (ApiHttpError error) {
        failure(error);
      },
    );
  }

三、实现上传队列

简单实现上传队列,这里上传采用一个接着一个上传,

代码如下

dart 复制代码
class UploaderQueue {

  // imagePath - key
  Function(Map<String, String> keys)? completion;

  Function(ApiHttpError error)? failure;

  UploaderQueue({
    this.completion,
    this.failure,
  });

  // 是否有任务正在进行时
  bool _isUploading = false;

  // 任务列表
  final List<String> _imagePathList = [];

  // 上传的keys
  final Map<String, String> _keyMap = {};

  // 上传的服务
  final UploaderTool _uploaderService = UploaderTool();

  void addImagePaths(List<String> imagePaths) {
    if (_isUploading) {
      return;
    }
    _imagePathList.addAll(imagePaths);
  }

  void doUpload() {
    if (_imagePathList.isEmpty) {
      return;
    }

    if (_isUploading) {
      return;
    }

    _isUploading = true;
    // 获取当前上传的图片ImagePath
    String imagePath = _imagePathList[0];

    _uploaderService.uploaderImage(imagePath, completion: (String key) {
      if (key.isNotEmpty) {
        _keyMap[imagePath] = key;
      }

      // 出队列
      _imagePathList.removeAt(0);
      _isUploading = false;

      if (_imagePathList.isNotEmpty) {
        // 不为空的时候
        doUpload();
      } else {
        if (completion != null) {
          completion!(_keyMap);
        }
      }
    }, failure: (ApiHttpError error) {
      cancel();
      if (failure != null) {
        failure!(error);
      }
    });
  }

  void cancel() {
    _isUploading = false;
    _imagePathList.clear();
  }

  void clear() {
    _isUploading = false;
    _imagePathList.clear();
  }
}

四、小结

flutter开发实战-文件上传及上传队列,获取token,上传图片到七牛。

学习记录,每天不停进步。

相关推荐
ii_best37 分钟前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk44 分钟前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
半点寒12W1 小时前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端2 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~2 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程2 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏2 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083163 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头4 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
一只叫煤球的猫4 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈