咱們公司的項目是圖片直接由客戶端上傳的七牛,而後在給咱們服務器傳七牛的地址。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/