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’,
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 createService(Class service){
mClient.addInterceptor(new HttpCommonInterceptor());
return builder.client(mClient.build()).build().create(service);
}
//获取对应的上传Service(带响应进度)
public T createReqeustService(Class service,ReqProgressCallBack callBack){
mClient.addInterceptor(new HttpReqeustInterceptor(callBack));
return builder.client(mClient.build()).build().create(service);
}
//获取对应的下载Service(带响应进度)
public T createResponseService(Class service,ReqProgressCallBack callBack){
mClient.addInterceptor(new HttpResponseInterceptor(callBack));
return builder.client(mClient.build()).build().create(service);
}
//文件下载
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);
}
}
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;
}
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;
}
}
public class RxHelper {
public static ObservableTransformer observableIO2Main(final Context context) {
return upstream -> {
Observable observable = upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
return composeContext(context, observable);
};
}
public static ObservableTransformer observableIO2Main(final RxFragment fragment) {
return upstream -> upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).compose(fragment.bindToLifecycle());
}
public static FlowableTransformer flowableIO2Main() {
return upstream -> upstream
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private static ObservableSource composeContext(Context context, Observable 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;
}
}
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();
}
}
public abstract class BaseObserver implements Observer
@Override
public void onSubscribe(Disposable d) {
LogUtils.loge("onSubscribe ===================》");
}
@Override
public void onNext(BaseResponse 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);
}
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;
}
}
public interface BaseApiService {
@POST
Observable> login();
@GET("20110628/1369025_192645024000_2.jpg")
Observable downLoadFile(); //doukx.apk
@GET()
Flowable get(@Url String url);
@GET()
Flowable get(@Url String url, @QueryMap Map maps);
@POST()
@FormUrlEncoded
Flowable post(@Url String url, @FieldMap Map maps);
@POST()
Flowable postBody(@Url String url, @Body Object object);
@DELETE()
Flowable delete(@Url String url, @QueryMap Map maps);
@PUT()
Flowable put(@Url String url, @QueryMap Map maps);
@POST()
Flowable putBody(@Url String url, @Body Object object);
@Multipart
@POST()
Flowable uploadFlie(@Url String fileUrl, @Part("description") RequestBody description, @Part("files") MultipartBody.Part file);
@Multipart
@POST()
Flowable uploadFiles(@Url String url, @PartMap() Map maps);
@Multipart
@POST()
Flowable uploadFiles(@Url String url, @Part() List parts);
@Streaming
@GET
Flowable downloadFile(@Url String fileUrl);
@POST()
@Headers({"Content-Type: application/json", "Accept: application/json"})
Flowable postJson(@Url String url, @Body RequestBody jsonBody);
@POST()
Flowable postBody(@Url String url, @Body RequestBody body);
}