21年初时,在无聊之际自己又手动封装了一次Rx + Retrofit 作为项目的网络框架,中间从Retrofit的入门使用 -> 单独封装Retrofit -> Rx + Retrofit 都又走了一次,回头一看时隔快一年了才开始记录…
Look here:封装之初,建议最好掌握Retrofit 和 RxJava、Android 的基础使用和原理,这样比较方便进行扩展或者改动 ~
- 基础配置
- Retrofit 相关
- UrlPath封装:HttpUrl
- 网络配置封装:RetrofitManager
- 接口封装:ApiService
- RxJava、RxAndroid 相关
- 基类响应体 :baseResponse
- 响应封装:baseObserver
- 线程管控:RxHelper
- 使用实践
提示:不可完全复制使用,但是可以批量借鉴、使用
基础配置AndroidMainfest 加入权限
build.gradle(app)加入依赖
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.squareup.okio:okio:1.15.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
Retrofit 相关
Retrofit网络封装,包含请求路径、网络配置、接口封装等
UrlPath封装:HttpUrl不可直接复用内部path,仅可借鉴
package com.example.rxandretrifit;
public class HttpUrl {
public static final String base_URL = "自己服务器域名";
//-----------------請求地址----------------//
public static final String SELF_PATH = "对应的接口 - path";
}
网络配置封装:RetrofitManager
基本可完全复用,大同小异
package com.example.rxandretrifit;
import android.util.Log;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitManager {
private static final int CONNECT_TIMEOUT = 15 * 1000;
private static final int READ_TIMEOUT = 15 * 1000;
private static final int WRITE_TIMEOUT = 15 * 1000;
private static final String TAG = "Retrofit-Interceptor";
private static RetrofitManager retrofitManager;
private ApiService apiService;
private OkHttpClient okHttpClient;
//单例调用
public static RetrofitManager getInstance() {
if (retrofitManager == null) {
synchronized (RetrofitManager.class) {
if (retrofitManager == null) {
retrofitManager = new RetrofitManager();
}
}
}
return retrofitManager;
}
private OkHttpClient getOkHttpClient() {
return okHttpClient == null ? initClient() : okHttpClient;
}
public ApiService getApiService() {
return apiService == null ? initRetrofit() : apiService;
}
private OkHttpClient initClient() {
//配置过滤器,常规有俩种过滤器的实现方式,有机会的话我补全
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i(TAG, "Http-Request-Response:" + message);
}
});
//不同环境下,过滤器的展示数据有所不同
if (BuildConfig.DEBUG) {
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
}
//进行配置
OkHttpClient.Builder okHttpClient = new OkHttpClient().newBuilder();
OkHttpClient client = okHttpClient
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
.addNetworkInterceptor(httpLoggingInterceptor)
//出错重连
.retryOnConnectionFailure(true)
.build();
return client;
}
ApiService initRetrofit() {
OkHttpClient client = getOkHttpClient();
Retrofit retrofit = new Retrofit
.Builder()
.baseUrl(HttpUrl.base_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
return retrofit.create(ApiService.class);
}
}
接口封装:ApiService
不可直接复用内部接口,仅可借鉴
package com.example.rxandretrifit;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Url;
public interface ApiService {
@GET(HttpUrl.SELF_PATH)
Observable> getMethod();
@FormUrlEncoded
@POST(HttpUrl.SELF_PATH)
Observable postMethod(@Field("参数1") String param1, @Field("参数2") String param2);
@FormUrlEncoded
@POST(HttpUrl.SELF_PATH)
Observable> postMethod(@FieldMap Map param);
}
RxJava、RxAndroid 相关
要想熟练结合 Rx + Retrofit的话,Rx的基础还是要掌握一下 ~
基类响应体 :baseResponse不可直接复用,仅可借鉴!
package com.example.rxandretrifit; class baseResponse响应封装:baseObserver{ private T extInfo; private String msg; private boolean success; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public T getExtInfo() { return extInfo; } public void setExtInfo(T extInfo) { this.extInfo = extInfo; } }
大部分可复用,但要注意定制化部分!!
package com.example.rxandretrifit; import android.util.Log; import com.google.gson.Gson; import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import org.json.JSONException; import java.io.IOException; import java.io.InterruptedIOException; import java.net.ConnectException; import java.net.UnknownHostException; import java.text.ParseException; import io.reactivex.Observer; import io.reactivex.annotations.NonNull; import io.reactivex.disposables.Disposable; import okhttp3.ResponseBody; import retrofit2.Response; public abstract class baseObserver线程管控:RxHelperimplements Observer > { private static String Tag = "retrofit-observer"; @Override public void onSubscribe(@NonNull Disposable d) { } @Override public void onComplete() { } @Override public void onError(Throwable e) { if (e instanceof HttpException) { onException(ExceptionReason.BAD_NETWORK); //-------此为个人扩展区间 start--------// Response response = ((HttpException) e).response(); ResponseBody responseBody = response.errorBody(); if (responseBody != null) { try { String errorResult = responseBody.string(); Gson gson = new Gson(); baseResponse br = gson.fromJson(errorResult, new TypeToken () { }.getType()); } catch (IOException ioException) { ioException.printStackTrace(); } } else { Log.e(Tag, Tag + ":responseBody==null;" + e.getMessage()); } //-------此为个人扩展区间 end--------// } else if (e instanceof ConnectException || e instanceof UnknownHostException) { onException(ExceptionReason.CONNECT_ERROR); } else if (e instanceof InterruptedIOException) { onException(ExceptionReason.CONNECT_TIMEOUT); } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) { onException(ExceptionReason.PARSE_ERROR); } else { onException(ExceptionReason.UNKNOWN_ERROR); } Log.e(Tag, Tag + e.getMessage()); onFailure(null, e.getMessage()); } @Override public void onNext(baseResponse response) { //以下部分都需要根据统一返回的基类进行处理,个性化定制,不可完全复制! if (response.isSuccess()) { onSuccess(response.getExtInfo()); } else { Log.e(Tag, Tag + ":" + response.getMsg()); onFailure(null, response.getMsg()); } } public abstract void onSuccess(T response); public abstract void onFailure(Throwable e, String errorMsg); public void onException(ExceptionReason reason) { switch (reason) { case CONNECT_ERROR: Log.e(Tag, "网络连接失败,请检查网络状态"); break; case CONNECT_TIMEOUT: Log.e(Tag, "网络超时,请检查网络状态"); break; case BAD_NETWORK: Log.e(Tag, "网络不给力,请稍后重试"); break; case PARSE_ERROR: Log.e(Tag, "解析失败,攻城狮正在修复"); break; case UNKNOWN_ERROR: default: Log.e(Tag, "未知错误"); break; } } public enum ExceptionReason { PARSE_ERROR, BAD_NETWORK, CONNECT_ERROR, CONNECT_TIMEOUT, UNKNOWN_ERROR, } }
可直接复用,主要用于子主线程切换
package com.example.rxandretrifit;
import android.content.Context;
import com.trello.rxlifecycle2.android.ActivityEvent;
import com.trello.rxlifecycle2.components.RxActivity;
import com.trello.rxlifecycle2.components.RxFragment;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
import com.trello.rxlifecycle2.components.support.RxFragmentActivity;
import io.reactivex.FlowableTransformer;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
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 static ObservableTransformer applySchedulers() {
return observable -> observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}
使用实践
- 图例版
- 代码版
RetrofitManager
.getInstance()
.getApiService()
.getMethod()
.compose(RxHelper.applySchedulers()).
subscribe(new baseObserver() {
@Override
public void onSuccess(TextModel response) {
Log.e("tag", "请求成功");
}
@Override
public void onFailure(Throwable e, String errorMsg) {
Log.e("tag", "请求失败");
}
});



