一、引入
- 七牛雲的官方SDK中只有單圖上傳。如果想要實現多圖的上傳可能會想到for迴圈,遞迴等解決方案.在這裡我分享下我用RxJava+回撥介面封裝的七牛雲多圖上傳工具類,也算是之前看了老多RxJava文章的一個實踐吧。如有不妥之處,還請多多指教啦?
二、先簡單說下七牛
我們公司的專案是圖片直接由客戶端上傳的七牛,然後在給我們伺服器傳七牛的地址。
-
引入依賴
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);
複製程式碼
三、在說幾個Rxjava的方法哈哈
括號中的內容為在當前專案中的用途
-
fromIterable(傳送原始資料,圖片地址集合)
可以接收一個 Iterable 容器作為輸入,每次發射一個元素
-
flatMap(將圖片地址轉為七牛雲上傳成功後的檔名,具體看程式碼吧)
FlatMap操作符使用一個指定的函式對原始Observable發射的每一項資料執行變換操作,這個函式返回一個本身也發射資料的Observable,然後FlatMap合併這些Observables發射的資料,最後將合併後的結果當做它自己的資料序列發射。
-
compose(切換執行緒)
compose()是唯一一個能夠從資料流中得到原始Observable的操作符,所以,那些需要對整個資料流產生作用的操作(比如,subscribeOn()和observeOn())需要使用compose()來實現。
-
為什麼不用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();
}
});
}複製程式碼
六、7月30日更新
為了確保圖片順序,將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/