咱们公司的项目是图片直接由客户端上传的七牛,而后在给咱们服务器传七牛的地址。java
引入依赖android
implementation 'com.qiniu:qiniu-android-sdk:7.3.+'
复制代码
七牛的图片上传数组
// 吐槽一下:token 官方推荐服务器生成,但是我司都是客户端本身搞。。。
// UploadManager uploadManager = new UploadManager(config);
data = <File对象、或 文件路径、或 字节数组>
String key = <指定七牛服务上的文件名,或 null>;
String token = <从服务端SDK获取>;
uploadManager.put(data, key, token,
new UpCompletionHandler() {
@Override
public void complete(String key, ResponseInfo info, JSONObject res) {
//res包含hash、key等信息,具体字段取决于上传策略的设置
if(info.isOK()) {
Log.i("qiniu", "Upload Success");
} else {
Log.i("qiniu", "Upload Fail");
//若是失败,这里能够把info信息上报本身的服务器,便于后面分析上传错误缘由
}
Log.i("qiniu", key + ",\r\n " + info + ",\r\n " + res);
}
}, null);
复制代码
括号中的内容为在当前项目中的用途bash
fromIterable(发送原始数据,图片地址集合)服务器
能够接收一个 Iterable 容器做为输入,每次发射一个元素dom
flatMap(将图片地址转为七牛云上传成功后的文件名,具体看代码吧)ide
FlatMap操做符使用一个指定的函数对原始Observable发射的每一项数据执行变换操做,这个函数返回一个自己也发射数据的Observable,而后FlatMap合并这些Observables发射的数据,最后将合并后的结果当作它本身的数据序列发射。函数
compose(切换线程)工具
compose()是惟一一个可以从数据流中获得原始Observable的操做符,因此,那些须要对整个数据流产生做用的操做(好比,subscribeOn()和observeOn())须要使用compose()来实现。spa
为何不用compose进行变换
答:由于compose是操做的整个流,FlatMap是操做的单独的事件。
public class QiNiuUtils {
private static String token = "通常是找本身服务器要";
/** * 七牛云SDK */
private static UploadManager uploadManager = new UploadManager();
/** * 回调接口 */
public interface QiNiuCallback {
/** * 上传完成 */
void onSuccess(List<String> picUrls);
/** * 上传失败 */
void onError(String msg);
}
/** * 上传图片到七牛 * * @param images 图片地址 * @param qiNiuCallback 回调接口 */
@SuppressLint("CheckResult")
public static void putImgs(List<String> images, QiNiuCallback qiNiuCallback) {
// 七牛返回的文件名
ArrayList<String> resultImagePath = new ArrayList<>();
Observable
// 依次发送list中的数据
.fromIterable(images)
// 变换,在这里上传图片
.flatMap((Function<String, ObservableSource<String>>)
path -> Observable.create(emitter -> {
String key = UUID.randomUUID().toString() + "." + path.split("\\.")[1];
uploadManager.put(path, key, token,
(key1, info, res) -> {
//res包含hash、key等信息,具体字段取决于上传策略的设置
if (info.isOK()) {
// 上传成功,发送这张图片的文件名
emitter.onNext(key1);
} else {
// 上传失败,告辞
emitter.onError(new IOException(info.error));
}
}, null);
})
)
// 线程切换
.compose(RxUtil.rxObservableSchedulerHelper())
.subscribe(response -> {
resultImagePath.add(response);
// 若是所有完成,调用成功接口
if (resultImagePath.size() == images.size()) {
qiNiuCallback.onSuccess(resultImagePath);
}
}, throwable -> {
LogUtils.e(throwable.getMessage());
qiNiuCallback.onError(throwable.getMessage());
});
}
}
复制代码
// pathResult 是图片地址集合
if (pathResult.size() > 0) {
showProgress();
QiNiuUtils.putImgs(pathResult, new QiNiuUtils.QiNiuCallback() {
@Override
public void onSuccess(List<String> picUrls) {
LogUtils.i(picUrls.toString());
showMsg("图片上传完成!");
hideProgress();
}
@Override
public void onError(String msg) {
hideProgress();
}
});
}
复制代码
为了确保图片顺序,将flatMap
修改成concatMap
。
注意:
emitter.onComplete();
public static void putImgs(List<String> images, QiNiuCallback qiNiuCallback) {
String token = Auth.create(Constants.QINIU_AK, Constants.QINIU_SK).uploadToken(Constants.QINIU_SCOPE);
// 七牛返回的文件名
ArrayList<String> resultImagePath = new ArrayList<>();
Observable
// 依次发送list中的数据
.fromIterable(images)
// 变换,在这里上传图片
// 修改成concatMap确保图片顺序
.concatMap((Function<String, ObservableSource<String>>) path ->
Observable.create((ObservableOnSubscribe<String>) emitter -> {
String key = UUID.randomUUID().toString() + "." + path.split("\\.")[1];
ResponseInfo responseInfo = uploadManager.syncPut(path, key, token, null);
if (responseInfo.isOK()) {
// 上传成功,发送这张图片的文件名
emitter.onNext(key);
emitter.onComplete();
} else {
// 上传失败,告辞
emitter.onError(new IOException(responseInfo.error));
}
}).subscribeOn(Schedulers.io())
)
// 线程切换
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> {
resultImagePath.add(response);
// 若是所有完成,调用成功接口
if (resultImagePath.size() == images.size()) {
qiNiuCallback.onSuccess(resultImagePath);
}
}, throwable -> {
LogUtils.e(throwable.getMessage());
qiNiuCallback.onError(throwable.getMessage());
});
}
复制代码
七牛云文档:https://developer.qiniu.com/kodo/sdk/1236/android
RxJava的简单使用:https://www.sdwfqin.com/2016/12/25/rxjava%E7%9A%84%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8/