阅读 2428

RxJava应用:实现七牛云多图上传

一、引入

  1. 七牛云的官方SDK中只有单图上传。如果想要实现多图的上传可能会想到for循环,递归等解决方案.在这里我分享下我用RxJava+回调接口封装的七牛云多图上传工具类,也算是之前看了老多RxJava文章的一个实践吧。如有不妥之处,还请多多指教啦😁

二、先简单说下七牛

我们公司的项目是图片直接由客户端上传的七牛,然后在给我们服务器传七牛的地址。

  1. 引入依赖

    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);
    
    复制代码

三、在说几个Rxjava的方法哈哈

括号中的内容为在当前项目中的用途

  1. fromIterable(发送原始数据,图片地址集合)

    可以接收一个 Iterable 容器作为输入,每次发射一个元素

  2. flatMap(将图片地址转为七牛云上传成功后的文件名,具体看代码吧)

    FlatMap操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据的Observable,然后FlatMap合并这些Observables发射的数据,最后将合并后的结果当做它自己的数据序列发射。

  3. compose(切换线程)

    compose()是唯一一个能够从数据流中得到原始Observable的操作符,所以,那些需要对整个数据流产生作用的操作(比如,subscribeOn()和observeOn())需要使用compose()来实现。

  4. 为什么不用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/

关注下面的标签,发现更多相似文章
评论