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,上传图片到七牛。
学习记录,每天不停进步。