flutter开发实战-文件上传及上传队列
之前开发中遇到了发帖子图片上传,上传到七牛。
一、实现Dio上传
上传使用到Dio上传功能,具体代码
// 上传文件(图片)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,failureApiHttpError apiHttpError =ApiHttpError(ApiHttpErrorType.Default, "请求失败!");if (failure != null) {failure(apiHttpError);}}} on DioError catch (e, s) {// catch到异常,failureLoggerManager().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
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实现上传
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);},);}
三、实现上传队列
简单实现上传队列,这里上传采用一个接着一个上传,
代码如下
class UploaderQueue {// imagePath - keyFunction(Map<String, String> keys)? completion;Function(ApiHttpError error)? failure;UploaderQueue({this.completion,this.failure,});// 是否有任务正在进行时bool _isUploading = false;// 任务列表final List<String> _imagePathList = [];// 上传的keysfinal 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;// 获取当前上传的图片ImagePathString 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,上传图片到七牛。
学习记录,每天不停进步。