Android封裝RxJava2+retrofit2實現徹底解耦網路層和邏輯層
更加優雅的實現網路請求
完整專案Github地址: ofollow,noindex">戳這裡!!!
前言
最近在用RxJava2+retrofit2來實現網路請求,一開始的時候我參考了這篇文章:
如何用RxJava2.0.7和Retrofit2.2.0優雅的實現網路請求 來封裝自己的網路請求的邏輯。
一開始的使用用的很爽,畢竟當初不會用Rxjava和retrofit時候,網路請求著實是一件十分痛苦的事情,要考慮的東西太多了。例如非同步發起請求,主執行緒中處理UI的變化。網路請求失敗後怎麼辦,網路很慢的時候如何展示一個通用的loading提示等等...現在大部分問題都能很好的得到解決,
但是仍然有其他不方便的地方在困擾著我們。
存在的問題
- 網路請求越來越多的情況下,會不停的在HttpMethods類中增加新的方法,網路請求的程式碼和業務邏輯緊緊的耦合在了一起,不符合我們程式員優雅的氣質。能不能把HttpMethods封裝好之後,不隨著業務的改變而變動呢?
- 每次傳送一個請求,都需要自己去處理rxjava中的onSubscribe(),onError(),onNext()和onComplete()方法。程式碼十分的冗餘。其實我們大部分時候只需要關心onNext()的回撥。其他的回撥方法做的事情幾乎一模一樣。
解決辦法
首先我們來看一下第一個問題:
其實HttpMethods處理業務邏輯最關鍵的方法是這個
public void getJoke(Observer<List<MyJoke>> observer){ apiService.getData() .subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer); } 作者:南柯一夢00 連結:https://www.jianshu.com/p/56f15db86ed3 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。
這個方法傳入了一個observer,然後用來接收回調,處理髮送請求之後的邏輯。我們只需要改造這個方法,就能解決我們的第一個問題。
public <T> T getRetrofitService(Class<T> cls) { return createRetrofit(BASE_URL).create(cls); }
private Retrofit createRetrofit(String baseUrl) { HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLogger()); logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient httpClient = new OkHttpClient().newBuilder() .readTimeout(DEFAULT_MILLISECONDS, TimeUnit.SECONDS) .connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.SECONDS) .writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.SECONDS) .retryOnConnectionFailure(true) .build(); return new Retrofit.Builder() .baseUrl(baseUrl) .client(httpClient) .addConverterFactory(GsonConverterFactory.create(new Gson())) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); }
現在來看第二個問題,我們發現之前是傳了一個叫observer的東西,然後就能處理onSubscribe(),onError(),onNext()和onComplete()方法,那麼我們可以吧observer封裝一下,提前處理好nSubscribe(),onError()和onComplete()方法,最後呼叫的時候只需要去處理onNext()就很完美了。
具體封裝邏輯如下:
public abstract class ObserverWrapper<T extends BaseResponse> extends DisposableObserver<T> { private IBaseApiAction apiAction; protected ObserverWrapper(IBaseApiAction apiAction) { this.apiAction = apiAction; } @Override protected void onStart() { super.onStart(); apiAction.showLoading(); } @Override public void onNext(T t) { if (t.isSuccess()) { Gson gson = new Gson(); success(t); Logger.i("開始列印伺服器返回資訊--->" + "\n" + "介面請求成功返回碼--->" + "\n" + t.getCode() + "\n" + "介面請求成功返回資訊--->" + "\n" + t.getMessage() + "\n" + "介面請求成功返回資料--->" + "\n" + gson.toJson(t) ); } else { apiAction.showToast(t.getMessage()); onFailure(t.getCode(), t.getMessage()); } apiAction.dismissLoading(); } @Override public void onError(Throwable e) { apiAction.dismissLoading(); onFailure(200, e.getMessage()); } @Override public void onComplete() { apiAction.dismissLoading(); complete(); } protected abstract void success(T t); private void onFailure(int code, String errorMsg) { apiAction.showToast(errorMsg); Logger.d("介面請求錯誤返回碼--->" + "\n" + code); Logger.d("介面請求錯誤資訊--->" + "\n" + errorMsg); } private void complete() { }
利用Java泛型的基礎來進行封裝,因為一般介面的返回都會帶上返回碼和返回資訊,所以可以根據這個來判斷處理介面請求的結果。
在onStart()方法中展示一個正在載入的動畫
在onFailure()方法中彈出吐司提示錯誤資訊
這個封裝就算完成啦~
執行結果:

image