淺談RxJava+Retrofit+OkHttp 封裝使用 之前發出后收到很多朋友的關注,原本只是自己學習后的一些經驗總結,但是有同學運用到實戰當中,這讓我很惶恐,所有后續一直更新了很多次版本,有些地方難免有所變動導致之前的博客有所出入,正好最近受到掘金邀請內測博客,所以決定重新寫一版,按照最后迭代完成的封裝詳細的講述一遍,歡迎大家關注!
注意:由于本章的特殊性,后續文章比較長而且復雜,涉及內容也很多,所以大家準備好茶水,前方高能預警。
簡介:
Retrofit: Retrofit是Square 公司開發的一款正對Android 網絡請求的框架。底層基于OkHttp 實現,OkHttp 已經得到了google 官方的認可。
OkHttp: 也是Square 開源的網絡請求庫
RxJava:RxJava 在 GitHub 主頁上的自我介紹是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫)。這就是 RxJava ,概括得非常精準。總之就是讓異步操作變得非常簡單。
各自的職責:Retrofit 負責請求的數據和請求的結果,使用接口的方式呈現,OkHttp 負責請求的過程,RxJava 負責異步,各種線程之間的切換。
RxJava + Retrofit + okHttp 已成為當前Android 網絡請求最流行的方式。
封裝成果
封裝完以后,具有如下功能:
	    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個方法呀!!!!反正我是忍受不了),而且以上處理還沒有做過多的判斷和錯誤校驗就如此復雜!~好了介紹完了,開始咱們的優化之路吧!
項目結構:
	
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.常用注解
這里介紹一些常用的注解的使用
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類并指定service的base 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(GET, POST, 等等。) 方法的注解以及用于分發網絡調用的方法。而且這些方法的參數也可以有特殊的注解。
/**  * 接口地址  * 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.結果判斷
這里結合RxJava的map方法在服務器返回數據中,統一處理數據處理,所以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}這里結合BaseApi的Func1判斷,失敗直接拋出一個異常,交個RxJava的onError處理,成功則將用戶關心的數據傳給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的實現類中數據初始化OkHttpClient和Retrofit對象,其中包含了url,超時等,接著通過BaseApi的抽象方法getObservable得到Observable對象,得到Observable對象以后,我們就能隨意的切換現成來處理,整個請求通過compose設定的rxlifecycle來管理生命周期,所以不會溢出和泄露無需任何擔心,最后再服務器數據返回時,通過map判斷結果,剔除錯誤信息,成功以后返回到自定義的ProgressSubscriber對象中,所以接下來封裝ProgressSubscriber對象。
ProgressSubscriber封裝
ProgressSubscriber其實是繼承于Subscriber,封裝的方法無非是對Subscriber的回調方法的封裝
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.異常統一處理
來個圖壓壓驚:
	
源碼:
RxRetrofit-終極封裝-深入淺出&網絡請求-GitHub
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答