RxJava應用:實現七牛雲多圖上傳

1、引入

  1. 七牛雲的官方SDK中只有單圖上傳。若是想要實現多圖的上傳可能會想到for循環,遞歸等解決方案.在這裏我分享下我用RxJava+回調接口封裝的七牛雲多圖上傳工具類,也算是以前看了老多RxJava文章的一個實踐吧。若有不妥之處,還請多多指教啦😁

2、先簡單說下七牛

咱們公司的項目是圖片直接由客戶端上傳的七牛,而後在給咱們服務器傳七牛的地址。java

  1. 引入依賴android

    implementation 'com.qiniu:qiniu-android-sdk:7.3.+'
    複製代碼
  2. 七牛的圖片上傳數組

    // 吐槽一下: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);
    
    複製代碼

3、在說幾個Rxjava的方法哈哈

括號中的內容爲在當前項目中的用途bash

  1. fromIterable(發送原始數據,圖片地址集合)服務器

    能夠接收一個 Iterable 容器做爲輸入,每次發射一個元素dom

  2. flatMap(將圖片地址轉爲七牛雲上傳成功後的文件名,具體看代碼吧)ide

    FlatMap操做符使用一個指定的函數對原始Observable發射的每一項數據執行變換操做,這個函數返回一個自己也發射數據的Observable,而後FlatMap合併這些Observables發射的數據,最後將合併後的結果當作它本身的數據序列發射。函數

  3. compose(切換線程)工具

    compose()是惟一一個可以從數據流中獲得原始Observable的操做符,因此,那些須要對整個數據流產生做用的操做(好比,subscribeOn()和observeOn())須要使用compose()來實現。spa

  4. 爲何不用compose進行變換

    答:由於compose是操做的整個流,FlatMap是操做的單獨的事件。

4、工具類代碼

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());
                });

    }
}
複製代碼

5、如何調用

// 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();
		}
	});
}
複製代碼

6、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());
            });
}
複製代碼

7、相關連接

七牛雲文檔: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/

相關文章
相關標籤/搜索