Android-封装网络请求Retrofit+Rxjava可实现上传下载进度监听

1.添加依赖

build.gradle:
//gson解析
api rootProject.ext.dependencies[“gson”]
api rootProject.ext.dependencies[“retrofit”]
//retrofit2.0
api rootProject.ext.dependencies[“adapter-rxjava2”]
//配合Rxjava 使用
api rootProject.ext.dependencies[“converter-gson”]
//ConverterFactory的Gson:
api rootProject.ext.dependencies[“rxjava”]
//rxjava
api rootProject.ext.dependencies[“rxandroid”]

config.gradle:
//gson解析
“gson” : ‘com.google.code.gson:gson:2.8.2’,
“retrofit” : ‘com.squareup.retrofit2:retrofit:2.0.2’,
//retrofit2.0
“adapter-rxjava2” : ‘com.squareup.retrofit2:adapter-rxjava2:2.3.0’,
//配合Rxjava 使用
“converter-gson” : ‘com.squareup.retrofit2:converter-gson:2.0.0-beta4’,
//ConverterFactory的Gson:
“rxjava” : ‘io.reactivex.rxjava2:rxjava:2.1.8’,
//rxjava
“rxandroid” : ‘io.reactivex.rxjava2:rxandroid:2.0.1’,
//日志拦截器
“logging-interceptor” : ‘com.squareup.okhttp3:logging-interceptor:3.5.0’,
//防止Rxjava引发的内存泄漏
“rxlifecycle” : ‘com.trello.rxlifecycle2:rxlifecycle-components:2.1.0’,

2.HttpManager.java 工具类

public class HttpManager {
//链接超时
private static int mConnectTimeout = 20;
//读超时
private static int mReadTimeOut = 20;
//写超时
private static int mWriteTimeOut = 20;
//okhttp请求的客户端
private OkHttpClient.Builder mClient;
//Retrofit请求Builder
private Retrofit.Builder builder;
//instance
private static volatile HttpManager instance;

//初始化
private HttpManager(){
    initOkHttp();
    initRetrofit();
}

//单例
public static HttpManager newInstance(){
    if (instance == null){
        synchronized (HttpManager.class){
            if (instance == null){
                instance = new HttpManager();
            }
        }
    }
    return instance;
}


//初始化OkHttpClient
private void initOkHttp(){
    mClient = new OkHttpClient.Builder();
    // 设置连接超时时间
    mClient.connectTimeout(mConnectTimeout, TimeUnit.SECONDS);
    // 设置读取数据超时时间
    mClient.readTimeout(mReadTimeOut, TimeUnit.SECONDS);
    // 设置写入超时时间
    mClient.writeTimeout(mWriteTimeOut,TimeUnit.SECONDS);
    // 设置进行连接失败重试
    mClient.retryOnConnectionFailure(true);
    //打印拦截器日志
    mClient.addNetworkInterceptor(new HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY));
}

//初始化Retrofit
private void initRetrofit(){
    builder = new Retrofit.Builder();
    builder.baseUrl(Api.BASE_URL);
    //Gson转换

// builder.addConverterFactory(LenientGsonConverterFactory.create());
builder.addConverterFactory(GsonConverterFactory.create());
//RxJava转换
builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
}

//获取对应的Service
public <T> T createService(Class<T> service){
    mClient.addInterceptor(new HttpCommonInterceptor());
    return builder.client(mClient.build()).build().create(service);
}

//获取对应的上传Service(带响应进度)
public <T> T createReqeustService(Class<T> service,ReqProgressCallBack callBack){
    mClient.addInterceptor(new HttpReqeustInterceptor(callBack));
    return builder.client(mClient.build()).build().create(service);
}

//获取对应的下载Service(带响应进度)
public <T> T createResponseService(Class<T> service,ReqProgressCallBack callBack){
    mClient.addInterceptor(new HttpResponseInterceptor(callBack));
    return builder.client(mClient.build()).build().create(service);
}           

3.添加拦截器HttpResponseInterceptor.java 和 HttpReqeustInterceptor.java

//文件下载
public class HttpResponseInterceptor implements Interceptor {

private ReqProgressCallBack callBack;

public HttpResponseInterceptor(ReqProgressCallBack callBack){
    this.callBack = callBack;
}

@Override
public Response intercept(Chain chain) throws IOException {
    Response response = chain.proceed(chain.request());
    //包装响应体
    return response.newBuilder().body(new ProgressResponseBody(response.body(),callBack)).build();
}

//文件上传
public class HttpReqeustInterceptor implements Interceptor {

private ReqProgressCallBack callBack;

public HttpReqeustInterceptor(ReqProgressCallBack callBack){
    this.callBack = callBack;
}

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    //包装响应体
    request.newBuilder().method(request.method(),
            new ProgressRequestBody(request.body(),callBack)).build();
    return chain.proceed(request);
}

}

4.重写ResponseBody监听文件下载进度

public class ProgressResponseBody extends ResponseBody {

private ResponseBody mResponseBody;
private BufferedSource mBufferedSource;
private ReqProgressCallBack callBack;

public ProgressResponseBody(ResponseBody body,ReqProgressCallBack callBack){
    this.mResponseBody = body;
    this.callBack = callBack;
}

@Nullable
@Override
public MediaType contentType() {
    return mResponseBody.contentType();
}

@Override
public long contentLength() {
    return mResponseBody.contentLength();
}

@Override
public BufferedSource source() {
    if (mBufferedSource == null){
        mBufferedSource = Okio.buffer(source(mResponseBody.source()));
    }
    return mBufferedSource;
}



private Source source(Source source){
    ForwardingSource so = new ForwardingSource(source) {
        long totalSize = 0l;
        @Override
        public long read(Buffer sink, long byteCount) throws IOException {
            long currentSize = super.read(sink,byteCount);
            // read() returns the number of bytes read, or -1 if this source is exhausted.
            totalSize += currentSize != -1 ? currentSize : 0;
            //当前下载的百分比进度
            int progress = (int) (totalSize * 100 / mResponseBody.contentLength());
            if (callBack != null){
                callBack.onProgress(FormatUtils.bytes2kb(mResponseBody.contentLength()),
                         FormatUtils.bytes2kb(totalSize),
                        progress + "%",currentSize == -1);
            }
            return currentSize;
        }
    };
    return so;
}

5.重写RequestBody监听文件上传进度

public class ProgressRequestBody extends RequestBody {

//实际的待包装请求体
private  RequestBody mRequestBody;
//进度回调接口
private ReqProgressCallBack mCallBack;
//包装完成的BufferedSink
private BufferedSink mSink;

public ProgressRequestBody(RequestBody body, ReqProgressCallBack callBack){
    this.mRequestBody = body;
    this.mCallBack = callBack;
}

@Override
public MediaType contentType() {
    return mRequestBody.contentType();
}

@Override
public long contentLength() throws IOException {
    return mRequestBody.contentLength();
}

@Override
public void writeTo(BufferedSink s) throws IOException {
    if (mSink == null){
        mSink = Okio.buffer(sink(s));
    }
    //写入
    mRequestBody.writeTo(mSink);
    //必须调用flush,否则最后一部分数据可能不会被写入
    mSink.flush();
}



private Sink sink(Sink sink){
    ForwardingSink s = new ForwardingSink(sink) {
        //当前写入字节数
        long currentSize = 0L;
        //总字节长度,避免多次调用contentLength()方法
        long totalSize = 0L;
        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            if (totalSize == 0) {
                //获得contentLength的值,后续不再调用
                totalSize = contentLength();
            }
            //增加当前写入的字节数
            currentSize += byteCount;
            //当前上传的百分比进度
            int progress = (int) (currentSize * 100 / totalSize);

// int progress = (int) (((float) currentSize) / ((float) totalSize) * 100);
boolean done = totalSize == currentSize;
//回调
if(mCallBack != null){
mCallBack.onProgress(FormatUtils.bytes2kb(totalSize),
FormatUtils.bytes2kb(currentSize),
progress + “”,done);
}
}
};
return s;
}
}

6.封装线程切换帮助类RxHelper.java

public class RxHelper {

public static <T> ObservableTransformer<T, T> observableIO2Main(final Context context) {
    return upstream -> {
        Observable<T> observable = upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        return composeContext(context, observable);
    };
}

public static <T> ObservableTransformer<T, T> observableIO2Main(final RxFragment fragment) {
    return upstream -> upstream.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).compose(fragment.<T>bindToLifecycle());
}

public static <T> FlowableTransformer<T, T> flowableIO2Main() {
    return upstream -> upstream
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

private static <T> ObservableSource<T> composeContext(Context context, Observable<T> observable) {
    if(context instanceof RxActivity) {
        return observable.compose(((RxActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
    } else if(context instanceof RxFragmentActivity){
        return observable.compose(((RxFragmentActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
    }else if(context instanceof RxAppCompatActivity){
        return observable.compose(((RxAppCompatActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
    }else {
        return observable;
    }
}

7.异常处理工具类RxExceptionUtil.java

public class RxExceptionUtil {

public static String exceptionHandler(Throwable e){
    if (e instanceof UnknownHostException){
        return  "网络不可用";
    }
    else if (e instanceof ConnectException){
        return "连接错误";
    }
    else if (e instanceof SocketTimeoutException){
        return "请求网络超时";
    }
    else if (e instanceof HttpException){
        return convertStatusCode((HttpException) e);
    }
        else if (e instanceof ParseException || e instanceof JSONException){
        return "数据解析错误";
    }
    return "未知错误";
}




private static String convertStatusCode(HttpException e){
    if (e.code() >= 500 && e.code() < 600){
        return "服务器处理请求出错";
    }
    else if (e.code() >= 400 && e.code() < 500){
        return "服务器无法处理请求";
    }
    else if (e.code() >= 300 && e.code() < 400){
        return "请求被重定向到其他页面";
    }
    return e.message();
}

}

8.封装BaseObserver.java

public abstract class BaseObserver implements Observer<BaseResponse> {

@Override
public void onSubscribe(Disposable d) {
    LogUtils.loge("onSubscribe ===================》");
}

@Override
public void onNext(BaseResponse<T> response) {
    LogUtils.loge("onNext ===================》");
    //对基础数据 进行统一处理
    if (response.isSuccess()){
        LogUtils.loge("开始打印数据===================》");
        LogUtils.loge(response.getData().toString());
        LogUtils.loge(response.getMessage());
        LogUtils.loge("结束打印数据===================》");
        onSuccess(response.getData());
    }else {
        onFailure(null,response.getMessage());
    }
}

@Override
public void onError(Throwable e) {
    LogUtils.loge("onError ===================》" + e.toString());
    onFailure(e, RxExceptionUtil.exceptionHandler(e));
}

@Override
public void onComplete() {
    LogUtils.loge("onComplete ===================》");
}

public abstract void onSuccess(T t);

public abstract void onFailure(Throwable e,String errorMsg);

}

9.封装JavaBean

public class BaseResponse {

private int status;
private String message;
private T data;

public boolean isSuccess(){
    return status == 200;
}

public int getStatus() {
    return status;
}

public void setStatus(int status) {
    this.status = status;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public T getData() {
    return data;
}

public void setData(T data) {
    this.data = data;
}

}

10.常用Api

public interface BaseApiService {

@POST
Observable<BaseResponse<LoginResponse>> login();


@GET("20110628/1369025_192645024000_2.jpg")
Observable<ResponseBody> downLoadFile(); //doukx.apk

@GET()
Flowable<ResponseBody> get(@Url String url);

@GET()
Flowable<ResponseBody> get(@Url String url, @QueryMap Map<String, String> maps);

@POST()
@FormUrlEncoded
Flowable<ResponseBody> post(@Url String url, @FieldMap Map<String, String> maps);

@POST()
Flowable<ResponseBody> postBody(@Url String url, @Body Object object);

@DELETE()
Flowable<ResponseBody> delete(@Url String url, @QueryMap Map<String, String> maps);

@PUT()
Flowable<ResponseBody> put(@Url String url, @QueryMap Map<String, String> maps);

@POST()
Flowable<ResponseBody> putBody(@Url String url, @Body Object object);

@Multipart
@POST()
Flowable<ResponseBody> uploadFlie(@Url String fileUrl, @Part("description") RequestBody description, @Part("files") MultipartBody.Part file);

@Multipart
@POST()
Flowable<ResponseBody> uploadFiles(@Url String url, @PartMap() Map<String, RequestBody> maps);

@Multipart
@POST()
Flowable<ResponseBody> uploadFiles(@Url String url, @Part() List<MultipartBody.Part> parts);

@Streaming
@GET
Flowable<ResponseBody> downloadFile(@Url String fileUrl);

@POST()
@Headers({"Content-Type: application/json", "Accept: application/json"})
Flowable<ResponseBody> postJson(@Url String url, @Body RequestBody jsonBody);

@POST()
Flowable<ResponseBody> postBody(@Url String url, @Body RequestBody body);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值