Andriod RX+Retrofit基础学习并简单封装
最近加入了新的工作,Android产品用了RX+retrofit作为网络交互框架,以前完全没用过,只有自己补一补。这里与大家分享一下学习成果,也便于自己日后复习。类似的文章特别多,封装也大同小异,特别记录一篇是希望自己将看过的东西能够真正理解变成自己的东西。
private void requestLogin(String name,String pwd){
APILoader personAPILoader=new APILoader();
personAPILoader.login(name,pwd)
.doOnNext(new Consumer<LoginBean>() {
@Override
public void accept(LoginBean loginBean) throws Exception {
}
})
.subscribe(new NetDisposable<>());
}
上面是笔者发起登陆请求的完整代码,还是比较简洁了吧。我们在doOnNext()中处理我们的结果逻辑,它会执行在onNext()之前。
下面我们由外至内一步一步来解析整套流程。
APILoader以及ObjectLoader
public class APILoader extends ObjectLoader {
private PersonAPI mPersonAPI;
public APILoader(){
mPersonAPI=RetrofitServiceManager.getInstance().create(PersonAPI.class);
}
public Observable<LoginBean> login(String name,String pwd){
return observe(mPersonAPI.loginRX(name,pwd));
}
}
public class ObjectLoader {
protected <T> Observable<T> observe(Observable<T> observable){
return observable
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}
ObjectLoader是我们自己实现的Loader父类,用于所有Loader类继承,封装了observe方法,参数和返回值都是Observable,作用是统一对Observable加工,处理一些重复操作,例如观察者与被观察者的线程处理。
APILoader继承自ObjectLoader,用于管理retrofit的ServiceAPI接口,避免每次使用都需要去create一次。所有的Loader统一继承ObjectLoader,对observable进行统一配置。
看到这里我们又出现了两个新玩意,分别是单例类RetrofitServiceManager以及接口PersonAPI。
接口PersonAPI
public interface PersonAPI {
@GET("td_web/td/login/")
Call<LoginBean> login(@Query("name") String name,@Query("pwd") String pwd);
@GET("td_web/td/login/")
Observable<LoginBean> loginRX(@Query("name") String name, @Query("pwd") String pwd);
}
这里的PersonAPI就是我们说的retrofit的ServiceAPI,在我看来是retrofit的精髓,采用接口注入的方式,创建和管理我们的请求接口
RetrofitServiceManager
public class RetrofitServiceManager {
private static final int DEFAULT_TIME_OUT = 5;//超时时间 5s
private static final int DEFAULT_READ_TIME_OUT = 10;//读写超时
private static final String BASE_URL="http://222.211.90.120:6071/";//根地址
private static RetrofitServiceManager retrofitServiceManager;
//日志显示级别
private Retrofit mRetrofit;
/**
* 获取RetrofitServiceManager
* @return
*/
public synchronized static RetrofitServiceManager getInstance(){
if(retrofitServiceManager==null) return new RetrofitServiceManager();
return retrofitServiceManager;
}
private RetrofitServiceManager(){
// 创建 OKHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//连接超时时间
builder.writeTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//写操作 超时时间
builder.readTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//读操作超时时间
builder.retryOnConnectionFailure(true);
// 添加公共参数拦截器
BasicParamsInterceptor basicParamsInterceptor = new BasicParamsInterceptor.Builder()
.addHeaderParam("paltform","android")
.addHeaderParam("userToken","1234343434dfdfd3434")
.addHeaderParam("userId","123445")
.build();
//添加日志打印拦截器
HttpLoggingInterceptor loggingInterceptor=new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);//设置日志显示级别
builder.addInterceptor(basicParamsInterceptor);
builder.addInterceptor(loggingInterceptor);
// 创建Retrofit
mRetrofit = new Retrofit.Builder()
.client(builder.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build();
}
/**
* 获取对应的Service
* @param service Service 的 class
* @param <T>
* @return
*/
public <T> T create(Class<T> service){
return mRetrofit.create(service);
}
}
retrofitServiceManager管理的是ServiceAPI的创建,对外公布create方法,返回ServiceApi实例
同时对OkHttpClient进行了封装和引入,可以对请求的公共参数,请求时间等进行添加和限制。
我们可以看到,这个一个单例类,在构造方法中我们可以统一的OkHttpClient进行配置以及添加拦截器等等。同时统一构建Retrofit的属性,只需要对外提供create方法,构建不同的ServiceAPI实例就可以了。
这里值得多提一句的是HttpLoggingInterceptor
。他是retrofit的日志拦截器,用于打印请求地址等等信息,可以通过setLevel设置打印信息的级别(级别越高,内容约详细)。retrofit做网络请求想要打印请求信息,暂时只发现这个方法,不像OkHttp3可以直接拿到url。
NetObserver网络请求观察者
一个简单封装的网络请求统一观察者,对网路请求常见的错误进行了管理和打印。
public class NetObserver<T> extends DisposableObserver<T> {
private String message="";
private final String TAG="NetObserver";
@Override
public void onNext(T t) {
}
@Override
public void onError(Throwable e) {
if (e instanceof HttpException) {
message = "网络错误";
} else if (e instanceof SocketTimeoutException) {
message = "网络连接超时";
} else if (e instanceof ConnectException) {
message = "连接失败";
} else if (e instanceof IOException) {
message = "网络错误";
} else if (e instanceof javax.net.ssl.SSLHandshakeException) {
message = "证书验证失败";
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
//均视为解析错误
message="数据解析出现错误";
} else {
message = "未知错误";
}
Log.e(TAG,message);
}
@Override
public void onComplete() {
}
}
参考文章:
【Android】RxJava2+Retrofit2+OkHttp3的基础、封装和项目中的使用