首先七牛android sdk 的普通上传代码是这样子的:
//重用 uploadManager。一般地,只需要创建一个 uploadManager 对象UploadManageruploadManager=newUploadManager();
data=<File对象、或文件路径、或字节数组>
String key=<指定七牛服务上的文件名,或null>;
Stringtoken=<从服务端SDK获取>;
uploadManager.put(data,key,token,newUpCompletionHandler({
@Overridepublicvoidcomplete(Stringkey,ResponseInfoinfo,JSONObjectres){
//res 包含hash、key等信息,具体字段取决于上传策略的设置。
Log.i("qiniu",key+",\r\n "+info+",\r\n "+res);
}
},null);
七牛上传是异步的,上传成功后会在UI线程回调
利用RxJava来封装,主要方法是:
public Observable upload(final String path,finalString key) {
return Observable.create(newObservable.OnSubscribe() {
@Override
public voidcall(final Subscriber subscriber) {
uploadManager.put(path,key, YebaConstants.QINIUTOKEN,
new UpCompletionHandler() {
@Override
public void complete(String key, ResponseInfo info, JSONObject res) {
if(info.isOK()){
subscriber.onNext(key);
subscriber.onCompleted();
}else{
LogUtil.e(info.toString());
APIError apiError=newAPIError(info.statusCode,info.error);
subscriber.onError(apiError);
}
},null);
}).retryWhen(new HttpTokenExpireFunc());
}
当上传失败时,把info的statusCode错误码和错误信息封装成apierror对象,交给onerror处理,这里用到了RxJava的retrywhen操作符,能让我们在subscrier处理onerror之前判断对错误进行解析处理,这里是为了让七牛token过期能自动获取,并且获取成功后继续之前失败的上传操作,不打断链式结构。
HttpTokenExpireFunc的代码如下:
/** * qiniu token 为空或者过期 重新获取 */
private class HttpTokenExpireFunc implements Func1<Observable<? extends Throwable>, Observable<?>> {
@Override
public Observable<?> call(Observable<? extends Throwable> observable) {
return observable.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
APIError apiError= (APIError) throwable;
if(apiError.getCode()==-4||apiError.getCode()==-5){
LogUtil.e("token过期或失效,重新获取");
return HttpApiUtils.getInstance().getQiNiuToken().doOnNext(new Action1<QiNiuToken>() {
@Override
public void call(QiNiuToken qiNiuToken) {
LogUtil.e("获取七牛token成功");
YebaConstants.QINIUTOKEN=qiNiuToken.getUpload_token();
}
});
}
return Observable.error(throwable);
}
});
}}
七牛的statuscode为-4,或-5表示token为空,或过期,这两种情况都需要重新获取,HttpApiUtils.getInstance().getQiNiuToken()为获取七牛token的方法,当获取成功后就把七牛token保存起来,这里只保存在内存中。当不是过期错误或为空时,发送一个错误出去Observable.error(throwable),之后就会进入subscriber的onerror处理。
网友评论