美文网首页AndroidAndroid开发Android开发经验谈
Android 简单封装 RxJava + Retrofit

Android 简单封装 RxJava + Retrofit

作者: 萌动小彩笔 | 来源:发表于2018-03-07 09:32 被阅读427次

    如今RxJava和Retrofit的结合使用估计已经相当普遍了,自己工作中也是一直都在使用。在使用的过程中我们都会对其进行封装使用,GitHub上也有很多封装好的项目可以直接拿来使用,其实对于开源框架的二次封装有时候针对不同的业务逻辑封装的过程中也多多少少有些不同,建议还是自己动手去封装使用。这样不仅提升自己对原框架的理解,还可以提高自己的封装能力。在工作过程中如需要改动便更加容易入手。好了,废话不多说,这里做了一个简单的样本供大家参考。


    添加依赖

    
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    
    compile 'io.reactivex.rxjava2:rxjava:2.x.y'
    
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    
    implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
    
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    
    

    添加依赖本并不想多说,我想大家都知道,但是对于刚接触这些知识的时候我想有没有人在看网上的文章时会觉得有些依赖是在哪找到并添加的呢?例如:com.squareup.retrofit2:converter-gson:2.3.0我们要添加一个GsonConverter的依赖。对于刚接触这些知识和不经常逛GitHub的人来说会不会一脸懵逼呢?不管会不会,反正我第一次接触的时候确实懵逼了下。这里给那些懵逼过的人提示下,我们可以通过打开GitHub上项目的子文件查看到相应的依赖。比如GitHub上Retrofit项目中:retrofit/retrofit-converters/gson/这个路径下就可以查看到相应的GsonConverter的依赖。

    封装Retrofit(单例模式)

    
    public class HttpRequest {
    
     public static final long CONNECTTIME = 30000;
    
     public static final String BASE_URL = "http://jxhdapi.ooowin.com/";
    
     private ApiService apiService;
    
     public HttpRequest() {
    
     //添加日志拦截器
    
     HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
    
     @Override
    
     public void log(String message) {
    
     Log.d("TAG", "==========" + message);
    
     }
    
     }).setLevel(HttpLoggingInterceptor.Level.BODY);
    
     //获取OkHttpClient
    
     OkHttpClient client = new OkHttpClient.Builder()
    
     .connectTimeout(CONNECTTIME, TimeUnit.MICROSECONDS)
    
     .readTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
    
     .writeTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
    
     .addInterceptor(interceptor)
    
     .addNetworkInterceptor(new HttpHeaderInterceptor())
    
     .build();
    
     //初始化Retrofit
    
     Retrofit retrofit = new Retrofit.Builder()
    
     .baseUrl(BASE_URL)
    
     .addConverterFactory(GsonConverterFactory.create())
    
     .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    
     .client(client)
    
     .build();
    
     apiService = retrofit.create(ApiService.class);
    
     }
    
     // 创建单例
    
     private static class SingletonHolder {
    
     private static final HttpRequest INSTANCE = new HttpRequest();
    
     }
    
     public static ApiService getApi(){
    
     return SingletonHolder.INSTANCE.apiService;
    
     }
    
    }
    
    

    这里我们可以看到添加了两个拦截器:日志拦截器和网络请求Header拦截器,我们都知道对于Retrofit我们是可以直接通过GsonConverter转换成实体类的,但有的时候我们又想去获取它的json数据进行查看,这个时候我们就可以通过添加日志拦截器实现,但一定要给它设置setLevel方法,设置不同的属性打印出来的数据是不一样的。至于添加Header拦截器我想大家都应该知道,正常工作中接口所需要的Header都是相同的,所以我们要进行统一添加:

    
    public class HttpHeaderInterceptor implements Interceptor {
    
     @Override
    
     public Response intercept(Chain chain) throws IOException {
    
     Request request = chain.request();
    
     Request build = request.newBuilder()
    
    // .addHeader("","")  添加header
    
     .build();
    
     return chain.proceed(build);
    
     }
    
    }
    
    

    封装实体类

    
    {
    
    "code": 1,
    
    "msg": "操作成功",
    
    "data": {······}
    
    }
    
    

    通常我们从服务端拿到的json数据就像上面那样,有些返回的字段内容格式是固定的,比如:code和msg。有些则是不确定,如:data。这个时候我们就需要对其进行二次处理了,我们可以写一个基类:

    
    public class BaseBean<T> {
    
     private int code;
    
     private String msg;
    
     private T data;
    
     public int getCode() {
    
     return code;
    
     }
    
     public void setCode(int code) {
    
     this.code = code;
    
     }
    
     public String getMsg() {
    
     return msg;
    
     }
    
     public void setMsg(String msg) {
    
     this.msg = msg;
    
     }
    
     public T getData() {
    
     return data;
    
     }
    
     public void setData(T data) {
    
     this.data = data;
    
     }
    
    }
    
    

    利用泛型来表示data中的不确定格式的数据,这里用一个获取全国所有省的数据接口进行测试:

    
    public interface ApiService {
    
     //获取省列表
    
     @GET("common/areas")
    
     Flowable<BaseBean<List<Province>>> province();
    
    }
    
    

    实体类封装好后我们可以进行一下测试:

    
    HttpRequest.getApi()
    
     .province()
    
     .subscribeOn(Schedulers.io())
    
     .observeOn(AndroidSchedulers.mainThread())
    
     .subscribe(new Subscriber<BaseBean<List<Province>>>() {
    
     @Override
    
     public void onSubscribe(Subscription s) {
    
     }
    
     @Override
    
     public void onNext(BaseBean<List<Province>> listBaseBean) {
    
     }
    
     @Override
    
     public void onError(Throwable t) {
    
     }
    
     @Override
    
     public void onComplete() {
    
     }
    
     });
    
    }
    
    

    通过上面的代码我们不难看出这是经过封装后的效果,但是我们会发现这样的请求我们难道每次都要去添加调度器和重写Subscriber的几个方法吗?那岂不还是很繁琐。是的,接下来我们就对这些进行封装。

    使用compose操作符

    
    public class SchedulersHelper implements FlowableTransformer{
    
     @Override
    
     public Publisher apply(Flowable upstream) {
    
     return upstream.subscribeOn(Schedulers.io())
    
     .observeOn(AndroidSchedulers.mainThread());
    
     }
    
    }
    
    

    使用compose操作符可以直接对当前Flowable进行操作,所以我们自然可以把切换线程的操作加入这里。接下来就是Subscriber进行封装了。

    封装Subscriber

    
    public abstract class MySubscriber<T> implements Subscriber<T>{
    
     @Override
    
     public void onSubscribe(Subscription s) {
    
     s.request(Long.MAX_VALUE);
    
     showLoading();
    
     }
    
     @Override
    
     public void onNext(T t) {
    
     //code为1代表服务器返回成功的数据
    
     if (((BaseBean)t).getCode() == 1) {
    
     //成功后返回data数据进行处理即可
    
     onSuccess((T) ((BaseBean) t).getData());
    
     }else {
    
     //处理服务器返回错误code
    
     }
    
     }
    
     @Override
    
     public void onComplete() {
    
     finishLoading();
    
     }
    
     @Override
    
     public void onError(Throwable t) {
    
     finishLoading();
    
     //处理网络异常
    
     Log.d("TAG","=========" + t);
    
     }
    
     protected abstract void onSuccess(T t);
    
     protected abstract void showLoading();
    
     protected abstract void finishLoading();
    
    }
    
    

    如上所示,我们根据服务端返回的code判断是否成功,将data数据传出去。服务器返回的错误码和网络请求错误我们都可以统一在这里进行处理。然后我们再去测试接口。

    测试

    
    HttpRequest.getApi().province()
    
     .compose(new SchedulersHelper())
    
     .subscribe(new MySubscriber() {
    
     @Override
    
     protected void onSuccess(Object o) {
    
     }
    
     @Override
    
     protected void showLoading() {
    
     }
    
     @Override
    
     protected void finishLoading() {
    
     }
    
     });
    
    

    可以的看到操作流程已经变的很简单了,对于showLoading()finishLoading()这两个方法我们可以不需要放在这里面,这个是我方便测试便将其写在里面了。

    结束

    到这里RxJava + Retrofit的封装就结束了,这是一个很简单封装过程,没有用到太多复杂的逻辑。比较通俗易懂,封装的完善度可能不是很高,大家可以当作一个参考,用自己的理解,更好的去封装它。之前有写过一篇简单的MVP基类,这个封装过程我便将它放在了上一篇的项目中。构成了一个简单易懂易上手的:RxJava + Retrofit + MVP的小Demo,放在了GitHub上,大家可以查看RxRetrofitMvp。如果你觉对你有帮助的话请,希望给个star哦,哈哈哈!

    相关文章

      网友评论

      本文标题:Android 简单封装 RxJava + Retrofit

      本文链接:https://www.haomeiwen.com/subject/kgndfftx.html