CSDN博客发布了一系列的RxJava+Retrofit+OkHttp深入浅出-终极封装 之前发出后收到很多朋友的关注,原本只是自己学习后的一些经验总结,但是有同学运用到实战当中,这让我很惶恐,所有后续一直更新了很多次版本,有些地方难免有所变动导致之前的博客有所出入,正好最近受到掘金邀请内测博客,所以决定重新写一版,按照最后迭代完成的封装详细的讲述一遍,欢迎大家关注!

注意:由于本章的特殊性,后续文章比较长而且复杂,涉及内容也很多,所以大家准备好茶水,前方高能预警。


RxJava+Retrofit+OkHttp深入浅出-终极封装


封装成果

封装完以后,具有如下功能:

    1.Retrofit+Rxjava+okhttp基本使用方法    2.统一处理请求数据格式    3.统一的ProgressDialog和回调Subscriber处理    4.取消http请求    5.预处理http请求    6.返回数据的统一判断    7.失败后的retry封装处理    8.RxLifecycle管理生命周期,防止泄露

实现效果:


具体使用

封装后http请求代码如下

//    完美封装简化版    private void simpleDo() {        SubjectPost postEntity = new SubjectPost(simpleOnNextListener,this);        postEntity.setAll(true);        HttpManager manager = HttpManager.getInstance();        manager.doHttpDeal(postEntity);    }    //   回调一一对应    HttpOnNextListener simpleOnNextListener = new HttpOnNextListener<List<Subject>>() {        @Override        public void onNext(List<Subject> subjects) {            tvMsg.setText("已封装:\n" + subjects.toString());        }        /*用户主动调用,默认是不需要覆写该方法*/        @Override        public void onError(Throwable e) {            super.onError(e);            tvMsg.setText("失败:\n" + e.toString());        }    };


是不是很简单?你可能说这还简单,好咱们对比一下正常使用Retrofit的方法


/**      * Retrofit加入rxjava实现http请求      */     private void onButton9Click() {         //手动创建一个OkHttpClient并设置超时时间         okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder();         builder.connectTimeout(5, TimeUnit.SECONDS);         Retrofit retrofit = new Retrofit.Builder()                 .client(builder.build())                 .addConverterFactory(GsonConverterFactory.create())                 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                 .baseUrl(HttpManager.BASE_URL)                 .build();  /        加载框         final ProgressDialog pd = new ProgressDialog(this);         HttpService apiService = retrofit.create(HttpService.class);         Observable<RetrofitEntity> observable = apiService.getAllVedioBy(true);         observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())                 .subscribe(                         new Subscriber<RetrofitEntity>() {                             @Override                             public void onCompleted() {                                 if (pd != null && pd.isShowing()) {                                     pd.dismiss();                                 }                             }                             @Override                             public void onError(Throwable e) {                                 if (pd != null && pd.isShowing()) {                                     pd.dismiss();                                 }                             }                             @Override                             public void onNext(RetrofitEntity retrofitEntity) {                                 tvMsg.setText("无封装:\n" + retrofitEntity.getData().toString());                             }                             @Override                             public void onStart() {                                 super.onStart();                                 pd.show();                             }                         }                 );     }


可能你发现确是代码有点多,但是更加可怕的是,如果你一个activity或者fragment中多次需要http请求,你需要多次重复的写回调处理(一个回到就有4个方法呀!!!!反正我是忍受不了),而且以上处理还没有做过多的判断和错误校验就如此复杂!~好了介绍完了,开始咱们的优化之路吧!


项目结构:



RxJava

如果你对RxJava不了解,好吧骚年赶快学学吧,不然真会out了,下面给出博主当初学习RxJava的一些资源:

  • 扔物线的金典RxJava
  • RxJava进阶一
  • RxJava进阶二
  • RxJava进阶三
  • RxJava进阶四

Retrofit

咱家今天的主角来了,咱们也深入浅出一下了解下Retrofit使用,前方高能,如果你是深度Retrofit选手请直接跳过本节!!!

1.首先确保在AndroidManifest.xml中请求了网络权限

<uses-permission android:name="android.permission.INTERNET"/>

2.在app/build.gradle添加引用

  /*rx-android-java*/    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'    compile 'com.trello:rxlifecycle:1.0'    compile 'com.trello:rxlifecycle-components:1.0'    /*rotrofit*/    compile 'com.squareup.retrofit2:retrofit:2.1.0'    compile 'com.squareup.retrofit2:converter-gson:2.0.0'    compile 'com.google.code.gson:gson:2.8.0'

3.常用注解

这里介绍一些常用的注解的使用

  • @Query@QueryMap:用于Http Get请求传递参数

  • @Field:用于Post方式传递参数,需要在请求接口方法上添加@FormUrlEncoded,即以表单的方式传递参数

  • @Body:用于Post,根据转换方式将实例对象转化为对应字符串传递参数.比如Retrofit添加GsonConverterFactory则是将body转化为gson字符串进行传递

  • @Path:用于URL上占位符

  • @Part:配合@Multipart使用,一般用于文件上传

  • @Header:添加http header

  • @Headers:跟@Header作用一样,只是使用方式不一样,@Header是作为请求方法的参数传入,@Headers是以固定方式直接添加到请求方法上

ReTrofit基本使用:

首先给定一个测试接口文档,后面的博客中我们都是用这个接口调试

/**   * @api    videoLink    50音图视频链接   * @url    http://www.izaodao.com/Api/AppFiftyToneGraph/videoLink   * @method post   * @param  once_no bool(选填,ture无链接) 一次性获取下载地址   * @return json array(   * ret:1成功,2失败   * msg:信息   * data:{   *       name:视频名称   *       title:标题   * }   )

1.初始化retrofit

要向一个api发送我们的网络请求 ,我们需要使用Retrofit builder类并指定servicebase URL(通常情况下就是域名)。

String BASE_URL = " http://www.izaodao.com/Api/"      Retrofit retrofit = new Retrofit.Builder()              .baseUrl(BASE_URL)              .addConverterFactory(GsonConverterFactory.create())              .build();


2.设置接口service

注意到每个endpoint 都指定了一个关于HTTP(GETPOST, 等等。) 方法的注解以及用于分发网络调用的方法。而且这些方法的参数也可以有特殊的注解。

/**   * 接口地址   * Created by WZG on 2016/7/16.   */  public interface MyApiEndpointInterface {      @POST("AppFiftyToneGraph/videoLink")      Call<RetrofitEntity> getAllVedio(@Body boolean once_no)             }


3.得到call然后同步处理处理回调:

MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);  Call<RetrofitEntity> call = apiService.getAllVedio(true);  call.enqueue(new Callback<RetrofitEntity>() {      @Override      public void onResponse(Response<RetrofitEntity> response, Retrofit retrofit) {          RetrofitEntity entity = response.body();          Log.i("tag", "onResponse----->" + entity.getMsg());      }      @Override      public void onFailure(Throwable t) {          Log.i("tag", "onFailure----->" + t.toString());      }  });

这就是简单的Retrofit使用步骤,接下来我们结合RxJava讲述


ReTrofit+Rxjava基本使用

对比之前的Retrofit使用

1.在于我们需要修改service接口返回信息我们需要返回一个Observable对象

@POST("AppFiftyToneGraph/videoLink")  Observable<RetrofitEntity> getAllVedioBy(@Body boolean once_no);

2.然后初始化Retrofit需要添加对Rxjava的适配,注意一定要retrofit2才有这个功能哦

Retrofit retrofit = new Retrofit.Builder()                  .client(builder.build())                  .addConverterFactory(GsonConverterFactory.create())                 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                  .baseUrl(HttpManager.BASE_URL)                  .build();

3.回调通过RxJava处理

HttpService apiService = retrofit.create(HttpService.class);         Observable<RetrofitEntity> observable = apiService.getAllVedioBy(true);         observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())                 .subscribe(                         new Subscriber<RetrofitEntity>() {                             @Override                             public void onCompleted() {                             }                             @Override                             public void onError(Throwable e) {                                                           }                             @Override                             public void onNext(RetrofitEntity retrofitEntity) {                                 tvMsg.setText("无封装:\n" + retrofitEntity.getData().toString());                             }                                                   }                 );

简单的RxJava集合Retrofit的使用就介绍完了,同样的可以发现使用起来很多重复性的代码,而且使用也不是那么简单,所以才有了下面的封装


ReTrofit+Rxjava进阶封装之路

先来一张流程图压压惊


请求数据封装

1.参数

首先需要封装的使我们的数据类,在数据类中需要封装请求中用到的相关数据的设置,比如请求参数、方法、加载框显示设置等等

public abstract class BaseApi<T> implements Func1<BaseResultEntity<T>, T> {    //rx生命周期管理    private SoftReference<RxAppCompatActivity> rxAppCompatActivity;    /*回调*/    private SoftReference<HttpOnNextListener> listener;    /*是否能取消加载框*/    private boolean cancel;    /*是否显示加载框*/    private boolean showProgress;    /*是否需要缓存处理*/    private boolean cache;    /*基础url*/    private  String baseUrl="http://www.izaodao.com/Api/";    /*方法-如果需要缓存必须设置这个参数;不需要不用設置*/    private String mothed;    /*超时时间-默认6秒*/    private int connectionTime = 6;    /*有网情况下的本地缓存时间默认60秒*/    private int cookieNetWorkTime=60;    /*无网络的情况下本地缓存时间默认30天*/    private int cookieNoNetWorkTime=24*60*60*30;}

注释很详细,这里不具体描述了,由于这里是最后封装完成以后的代码,所以有些内容本章还会部分不会涉及,因为功能太多,还是按照一开始的博客章节讲解。

2.抽象api接口

    /**     * 设置参数     *     * @param retrofit     * @return     */    public abstract Observable getObservable(Retrofit retrofit);

通过子类也即是我们的具体api接口,通过getObservable实现service中定义的接口方法,例如:

public class SubjectPostApi extends BaseApi {     xxxxxxx     xxxxxxx @Override    public Observable getObservable(Retrofit retrofit) {        HttpPostService service = retrofit.create(HttpPostService.class);        return service.getAllVedioBys(isAll());    }}

通过传入的Retrofit对象,可以随意切换挑选Service对象,得到定义的注解方法,初始完成以后返回Observable对象。

3.结果判断

这里结合RxJavamap方法在服务器返回数据中,统一处理数据处理,所以BaseApi<T> implements Func1<BaseResultEntity<T>, T>,后边结合结果处理链接起来使用

    @Override    public T call(BaseResultEntity<T> httpResult) {        if (httpResult.getRet() == 0) {            throw new HttpTimeException(httpResult.getMsg());        }        return httpResult.getData();    }

由于测试接口,也是当前我们公司接口都是有统一规则的,想必大家都有这样的接口规则,所以才有这里的统一判断,规则如下:

 * ret:1成功,2失败   * msg:信息   * data:{   *       name:视频名称   *       title:标题   * }

其实上面的接口文档中就介绍了,统一先通过ret判断,失败显示msg信息,data是成功后的数据也就是用户关心的数据,所以可封装一个结果对象BaseResultEntity.

4.结果数据

/** * 回调信息统一封装类 * Created by WZG on 2016/7/16. */public class BaseResultEntity<T> {    //  判断标示    private int ret;    //    提示信息    private String msg;    //显示数据(用户需要关心的数据)    private T data;    xxxxx  get-set  xxxxx}

这里结合BaseApiFunc1判断,失败直接抛出一个异常,交个RxJavaonError处理,成功则将用户关心的数据传给Gson解析返回

5.泛型传递

BaseResultEntity<T>中的泛型T也就是我们所关心的回调数据,同样也是Gson最后解析返回的数据,传递的过程根节点是通过定义service方法是给定的,例如:

public interface HttpPostService {    @POST("AppFiftyToneGraph/videoLink")    Call<RetrofitEntity> getAllVedio(@Body boolean once_no);}

其中的RetrofitEntity就是用户关心的数据类,通过泛型传递给最后的接口。

6.强调

很多兄弟通过QQ群反馈给我说,使用一个接口需要写一个对应的api类继承BaseApi是不是很麻烦,我这里强调一下,这样封装是为了将一个Api接口作为一个对象去封装,个人觉得有必要封装成一个类,在日后工程日益增加接口随着增加的同时,对象的做法更加有利于查找接口和修改接口有利于迭代。


操作类封装

1初始对象

首先初始化一个单利方便HttpManager请求;这里用了volatile的对象,不懂的同学可以参考我的另一篇博客

你真的会写单例吗

    private volatile static HttpManager INSTANCE;    //构造方法私有    private HttpManager() {    }    //获取单例    public static HttpManager getInstance() {        if (INSTANCE == null) {            synchronized (HttpManager.class) {                if (INSTANCE == null) {                    INSTANCE = new HttpManager();                }            }        }        return INSTANCE;    }

2接口处理和回调处理:

 /**     * 处理http请求     *     * @param basePar 封装的请求数据     */    public void doHttpDeal(BaseApi basePar) {        //手动创建一个OkHttpClient并设置超时时间缓存等设置        OkHttpClient.Builder builder = new OkHttpClient.Builder();        builder.connectTimeout(basePar.getConnectionTime(), TimeUnit.SECONDS);        builder.addInterceptor(new CookieInterceptor(basePar.isCache()));        /*创建retrofit对象*/        Retrofit retrofit = new Retrofit.Builder()                .client(builder.build())                .addConverterFactory(GsonConverterFactory.create())                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                .baseUrl(basePar.getBaseUrl())                .build();        /*rx处理*/        ProgressSubscriber subscriber = new ProgressSubscriber(basePar);        Observable observable = basePar.getObservable(retrofit)                /*失败后的retry配置*/                .retryWhen(new RetryWhenNetworkException())                /*生命周期管理*/                .compose(basePar.getRxAppCompatActivity().bindToLifecycle())                /*http请求线程*/                .subscribeOn(Schedulers.io())                .unsubscribeOn(Schedulers.io())                /*回调线程*/                .observeOn(AndroidSchedulers.mainThread())                /*结果判断*/                .map(basePar);        /*数据回调*/        observable.subscribe(subscriber);    }

首先通过api接口类BaseApi的实现类中数据初始化OkHttpClientRetrofit对象,其中包含了url,超时等,接着通过BaseApi的抽象方法getObservable得到Observable对象,得到Observable对象以后,我们就能随意的切换现成来处理,整个请求通过compose设定的rxlifecycle来管理生命周期,所以不会溢出和泄露无需任何担心,最后再服务器数据返回时,通过map判断结果,剔除错误信息,成功以后返回到自定义的ProgressSubscriber对象中,所以接下来封装ProgressSubscriber对象。


ProgressSubscriber封装

ProgressSubscriber其实是继承于Subscriber,封装的方法无非是对Subscriber的回调方法的封装

  • onStart():开始
  • onCompleted():结束
  • onError(Throwable e):错误
  • onNext(T t):成功

1.请求加载框

http请求都伴随着加载框的使用,所以这里需要在onStart()使用前初始一个加载框,这里简单的用ProgressDialog代替

/** * 用于在Http请求开始时,自动显示一个ProgressDialog * 在Http请求结束是,关闭ProgressDialog * 调用者自己对请求数据进行处理 * Created by WZG on 2016/7/16. */public class ProgressSubscriber<T> extends Subscriber<T> {    /*是否弹框*/    private boolean showPorgress = true;    /* 软引用回调接口*/    private SoftReference<HttpOnNextListener> mSubscriberOnNextListener;    /*软引用反正内存泄露*/    private SoftReference<RxAppCompatActivity> mActivity;    /*加载框可自己定义*/    private ProgressDialog pd;    /*请求数据*/    private BaseApi api;    /**     * 构造     *     * @param api     */    public ProgressSubscriber(BaseApi api) {        this.api = api;        this.mSubscriberOnNextListener = api.getListener();        this.mActivity = new SoftReference<>(api.getRxAppCompatActivity());        setShowPorgress(api.isShowProgress());        if (api.isShowProgress()) {            initProgressDialog(api.isCancel());        }    }    /**     * 初始化加载框     */    private void initProgressDialog(boolean cancel) {        Context context = mActivity.get();        if (pd == null && context != null) {            pd = new ProgressDialog(context);            pd.setCancelable(cancel);            if (cancel) {                pd.setOnCancelListener(new DialogInterface.OnCancelListener() {                    @Override                    public void onCancel(DialogInterface dialogInterface) {                        onCancelProgress();                    }                });            }        }    }    /**     * 显示加载框     */    private void showProgressDialog() {        if (!isShowPorgress()) return;        Context context = mActivity.get();        if (pd == null || context == null) return;        if (!pd.isShowing()) {            pd.show();        }    }    /**     * 隐藏     */    private void dismissProgressDialog() {        if (!isShowPorgress()) return;        if (pd != null && pd.isShowing()) {            pd.dismiss();        }    }}

由于progress的特殊性,需要指定content而且不能是Application所以这里传递一个RxAppCompatActivity,而同时上面的HttpManager同样需要,所以这里统一还是按照BaseApi传递过来,使用软引用的方式避免泄露。剩下的无非是初始化,显示和关闭方法,可以详细看代码。

2.onStart()实现

onStart()中需要调用加载框,然后这里还有网络缓存的逻辑,后面会单独讲解,现在先忽略它的存在。

 /**     * 订阅开始时调用     * 显示ProgressDialog     */    @Override    public void onStart() {        showProgressDialog();        /*缓存并且有网*/        if (api.isCache() && AppUtil.isNetworkAvailable(RxRetrofitApp.getApplication())) {             /*获取缓存数据*/            CookieResulte cookieResulte = CookieDbUtil.getInstance().queryCookieBy(api.getUrl());            if (cookieResulte != null) {                long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000;                if (time < api.getCookieNetWorkTime()) {                    if (mSubscriberOnNextListener.get() != null) {                        mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());                    }                    onCompleted();                    unsubscribe();                }            }        }    }

3.onCompleted()实现

 /**     * 完成,隐藏ProgressDialog     */    @Override    public void onCompleted() {        dismissProgressDialog();    }

4.onError(Throwable e)实现

onError(Throwable e)是对错误信息的处理和缓存读取的处理,后续会讲解,先忽略。

/**     * 对错误进行统一处理     * 隐藏ProgressDialog     *     * @param e     */    @Override    public void onError(Throwable e) {        dismissProgressDialog();        /*需要緩存并且本地有缓存才返回*/        if (api.isCache()) {            Observable.just(api.getUrl()).subscribe(new Subscriber<String>() {                @Override                public void onCompleted() {                }                @Override                public void onError(Throwable e) {                    errorDo(e);                }                @Override                public void onNext(String s) {                    /*获取缓存数据*/                    CookieResulte cookieResulte = CookieDbUtil.getInstance().queryCookieBy(s);                    if (cookieResulte == null) {                        throw new HttpTimeException("网络错误");                    }                    long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000;                    if (time < api.getCookieNoNetWorkTime()) {                        if (mSubscriberOnNextListener.get() != null) {                            mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());                        }                    } else {                        CookieDbUtil.getInstance().deleteCookie(cookieResulte);                        throw new HttpTimeException("网络错误");                    }                }            });        } else {            errorDo(e);        }    }    /*错误统一处理*/    private void errorDo(Throwable e) {        Context context = mActivity.get();        if (context == null) return;        if (e instanceof SocketTimeoutException) {            Toast.makeText(context, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();        } else if (e instanceof ConnectException) {            Toast.makeText(context, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();        } else {            Toast.makeText(context, "错误" + e.getMessage(), Toast.LENGTH_SHORT).show();        }        if (mSubscriberOnNextListener.get() != null) {            mSubscriberOnNextListener.get().onError(e);        }    }

5.onNext(T t)实现

   /**     * 将onNext方法中的返回结果交给Activity或Fragment自己处理     *     * @param t 创建Subscriber时的泛型类型     */    @Override    public void onNext(T t) {        if (mSubscriberOnNextListener.get() != null) {            mSubscriberOnNextListener.get().onNext(t);        }    }

主要是是将得到的结果,通过自定义的接口返回给view界面,其中的软引用对象mSubscriberOnNextListener是自定义的接口回调类HttpOnNextListener.


6.HttpOnNextListener封装

现在只需关心onNext(T t)onError(Throwable e)接口即可,回调的触发点都是在上面的ProgressSubscriber中调用

/** * 成功回调处理 * Created by WZG on 2016/7/16. */public abstract class HttpOnNextListener<T> {    /**     * 成功后回调方法     * @param t     */    public abstract void onNext(T t);    /**     * 緩存回調結果     * @param string     */    public void onCacheNext(String string){    }    /**     * 失败或者错误方法     * 主动调用,更加灵活     * @param e     */    public  void onError(Throwable e){    }    /**     * 取消回調     */    public void onCancel(){    }}

失败后的retry处理

这里你可能会问,Retrofit有自带的retry处理呀,的确Retrofit有自带的retry处理,但是有很多的局限,先看下使用

OkHttpClient.Builder builder = new OkHttpClient.Builder();builder.retryOnConnectionFailure(true);

使用起来还是很方便,只需要调用一个方法即可,但是它是不可控的,也就是没有办法设置retry时间次数,所以不太灵活,既然如此还不如自己封装一下,因为用RxJava实现这个简直小菜,无形中好像已经给RxJava打了广告,中毒太深。

很简单直接上代码:

 /** * retry条件 * Created by WZG on 2016/10/17. */public class RetryWhenNetworkException implements Func1<Observable<? extends Throwable>, Observable<?>> {//    retry次数    private int count = 3;//    延迟    private long delay = 3000;//    叠加延迟    private long increaseDelay = 3000;    public RetryWhenNetworkException() {    }    public RetryWhenNetworkException(int count, long delay) {        this.count = count;        this.delay = delay;    }    public RetryWhenNetworkException(int count, long delay, long increaseDelay) {        this.count = count;        this.delay = delay;        this.increaseDelay = increaseDelay;    }    @Override    public Observable<?> call(Observable<? extends Throwable> observable) {        return observable                .zipWith(Observable.range(1, count + 1), new Func2<Throwable, Integer, Wrapper>() {                    @Override                    public Wrapper call(Throwable throwable, Integer integer) {                        return new Wrapper(throwable, integer);                    }                }).flatMap(new Func1<Wrapper, Observable<?>>() {                    @Override                    public Observable<?> call(Wrapper wrapper) {                        if ((wrapper.throwable instanceof ConnectException                                || wrapper.throwable instanceof SocketTimeoutException                                || wrapper.throwable instanceof TimeoutException)                                && wrapper.index < count + 1) { //如果超出重试次数也抛出错误,否则默认是会进入onCompleted                            return Observable.timer(delay + (wrapper.index - 1) * increaseDelay, TimeUnit.MILLISECONDS);                        }                        return Observable.error(wrapper.throwable);                    }                });    }    private class Wrapper {        private int index;        private Throwable throwable;        public Wrapper(Throwable throwable, int index) {            this.index = index;            this.throwable = throwable;        }    }}

使用

到这里,我们第一步封装已经完成了,下面讲解下如何使用,已经看明白的各位看官,估计早就看明白了使用方式,无非是创建一个api对象继承BaseApi初始接口信息,然后调用HttpManager对象的doHttpDeal(BaseApi basePar)方法,最后静静的等待回调类HttpOnNextListener<T>类返回的onNext(T t)成功数据或者onError(Throwable e)数据。

其实代码就是这样:

api接口对象

/** * 测试数据 * Created by WZG on 2016/7/16. */public class SubjectPostApi extends BaseApi {//    接口需要传入的参数 可自定义不同类型    private boolean all;    /*任何你先要传递的参数*///    String xxxxx;    /**     * 默认初始化需要给定回调和rx周期类     * 可以额外设置请求设置加载框显示,回调等(可扩展)     * @param listener     * @param rxAppCompatActivity     */    public SubjectPostApi(HttpOnNextListener listener, RxAppCompatActivity rxAppCompatActivity) {        super(listener,rxAppCompatActivity);        setShowProgress(true);        setCancel(true);        setCache(true);        setMothed("AppFiftyToneGraph/videoLink");        setCookieNetWorkTime(60);        setCookieNoNetWorkTime(24*60*60);    }    public boolean isAll() {        return all;    }    public void setAll(boolean all) {        this.all = all;    }    @Override    public Observable getObservable(Retrofit retrofit) {        HttpPostService service = retrofit.create(HttpPostService.class);        return service.getAllVedioBys(isAll());    }}

请求回调

    //    完美封装简化版    private void simpleDo() {        SubjectPostApi postEntity = new SubjectPostApi(simpleOnNextListener,this);        postEntity.setAll(true);        HttpManager manager = HttpManager.getInstance();        manager.doHttpDeal(postEntity);    }    //   回调一一对应    HttpOnNextListener simpleOnNextListener = new HttpOnNextListener<List<SubjectResulte>>() {        @Override        public void onNext(List<SubjectResulte> subjects) {            tvMsg.setText("网络返回:\n" + subjects.toString());        }        @Override        public void onCacheNext(String cache) {            /*缓存回调*/            Gson gson=new Gson();            java.lang.reflect.Type type = new TypeToken<BaseResultEntity<List<SubjectResulte>>>() {}.getType();            BaseResultEntity resultEntity= gson.fromJson(cache, type);            tvMsg.setText("缓存返回:\n"+resultEntity.getData().toString() );        }        /*用户主动调用,默认是不需要覆写该方法*/        @Override        public void onError(Throwable e) {            super.onError(e);            tvMsg.setText("失败:\n" + e.toString());        }        /*用户主动调用,默认是不需要覆写该方法*/        @Override        public void onCancel() {            super.onCancel();            tvMsg.setText("取消請求");        }    };

后续

到这里,封装功能中很多功能还没涉及和讲解,后续会陆续更新!
先给大家看看为师的完全体功能:

    1.Retrofit+Rxjava+okhttp基本使用方法    2.统一处理请求数据格式    3.统一的ProgressDialog和回调Subscriber处理    4.取消http请求    5.预处理http请求    6.返回数据的统一判断    7.失败后的retry处理    8.RxLifecycle管理生命周期,防止泄露    9.文件上传下载(支持多文件,断点续传)    10.Cache数据持久化和数据库(greenDao)两种缓存机制    11.异常统一处理

来个图压压惊:

迫不及待的小伙伴可以看这里:

RxJava+Retrofit+OkHttp深入浅出-终极封装

但是其中有些后续优化迭代未及时更新,别生气,我马上补!


源码:

RxRetrofit-终极封装-深入浅出&网络请求-GitHub

其实我还有一个兄弟版本-传送门

我不会告诉你其实我还有个更加简单的版本


建议

如果你对这套封装有任何的问题和建议欢迎加入QQ群告诉我