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;
// builder.addConverterFactory(LenientGsonConverterFactory.create());
builder.addConverterFactory(GsonConverterFactory.create());
//RxJava轉換
builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
}
3.添加攔截器HttpResponseInterceptor.java 和 HttpReqeustInterceptor.java
//文件下載
public class HttpResponseInterceptor implements Interceptor {
//文件上傳
public class HttpReqeustInterceptor implements Interceptor {
}
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;@Overridepublic 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;@Overridepublic 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);}
總結
以上是生活随笔為你收集整理的Android-封装网络请求Retrofit+Rxjava可实现上传下载进度监听的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux【学习心得】深入剖析软件的源码
- 下一篇: 2016最新申请搜狐自媒体的6点官方建议