Android?RxJava與Retrofit結(jié)合使用詳解
如今RxJava和Retrofit的結(jié)合使用估計(jì)已經(jīng)相當(dāng)普遍了,自己工作中也是一直都在使用。在使用的過(guò)程中我們都會(huì)對(duì)其進(jìn)行封裝使用,GitHub上也有很多封裝好的項(xiàng)目可以直接拿來(lái)使用,其實(shí)對(duì)于開(kāi)源框架的二次封裝有時(shí)候針對(duì)不同的業(yè)務(wù)邏輯封裝的過(guò)程中也多多少少有些不同,建議還是自己動(dòng)手去封裝使用。這樣不僅提升自己對(duì)原框架的理解,還可以提高自己的封裝能力。在工作過(guò)程中如需要改動(dòng)便更加容易入手。好了,廢話不多說(shuō),這里做了一個(gè)簡(jiǎn)單的樣本供大家參考。
添加依賴
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'
添加依賴本并不想多說(shuō),我想大家都知道,但是對(duì)于剛接觸這些知識(shí)的時(shí)候我想有沒(méi)有人在看網(wǎng)上的文章時(shí)會(huì)覺(jué)得有些依賴是在哪找到并添加的呢?例如:com.squareup.retrofit2:converter-gson:2.3.0
我們要添加一個(gè)GsonConverter
的依賴。對(duì)于剛接觸這些知識(shí)和不經(jīng)常逛GitHub的人來(lái)說(shuō)會(huì)不會(huì)一臉懵逼呢?不管會(huì)不會(huì),反正我第一次接觸的時(shí)候確實(shí)懵逼了下。這里給那些懵逼過(guò)的人提示下,我們可以通過(guò)打開(kāi)GitHub上項(xiàng)目的子文件查看到相應(yīng)的依賴。比如GitHub上Retrofit項(xiàng)目中:retrofit/retrofit-converters/gson/
這個(gè)路徑下就可以查看到相應(yīng)的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); } // 創(chuàng)建單例 private static class SingletonHolder { private static final HttpRequest INSTANCE = new HttpRequest(); } public static ApiService getApi(){ return SingletonHolder.INSTANCE.apiService; } }
這里我們可以看到添加了兩個(gè)攔截器:日志攔截器和網(wǎng)絡(luò)請(qǐng)求Header攔截器,我們都知道對(duì)于Retrofit我們是可以直接通過(guò)GsonConverter
轉(zhuǎn)換成實(shí)體類的,但有的時(shí)候我們又想去獲取它的json數(shù)據(jù)進(jìn)行查看,這個(gè)時(shí)候我們就可以通過(guò)添加日志攔截器實(shí)現(xiàn),但一定要給它設(shè)置setLevel
方法,設(shè)置不同的屬性打印出來(lái)的數(shù)據(jù)是不一樣的。至于添加Header攔截器我想大家都應(yīng)該知道,正常工作中接口所需要的Header都是相同的,所以我們要進(jìn)行統(tǒng)一添加:
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); } }
封裝實(shí)體類
{ "code": 1, "msg": "操作成功", "data": {······} }
通常我們從服務(wù)端拿到的json數(shù)據(jù)就像上面那樣,有些返回的字段內(nèi)容格式是固定的,比如:code和msg。有些則是不確定,如:data。這個(gè)時(shí)候我們就需要對(duì)其進(jìn)行二次處理了,我們可以寫一個(gè)基類:
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; } }
利用泛型來(lái)表示data中的不確定格式的數(shù)據(jù),這里用一個(gè)獲取全國(guó)所有省的數(shù)據(jù)接口進(jìn)行測(cè)試:
public interface ApiService { //獲取省列表 @GET("common/areas") Flowable<BaseBean<List<Province>>> province(); }
實(shí)體類封裝好后我們可以進(jìn)行一下測(cè)試:
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() { } }); }
通過(guò)上面的代碼我們不難看出這是經(jīng)過(guò)封裝后的效果,但是我們會(huì)發(fā)現(xiàn)這樣的請(qǐng)求我們難道每次都要去添加調(diào)度器和重寫Subscriber
的幾個(gè)方法嗎?那豈不還是很繁瑣。是的,接下來(lái)我們就對(duì)這些進(jìn)行封裝。
使用compose操作符
public class SchedulersHelper implements FlowableTransformer{ @Override public Publisher apply(Flowable upstream) { return upstream.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }
使用compose操作符可以直接對(duì)當(dāng)前Flowable進(jìn)行操作,所以我們自然可以把切換線程的操作加入這里。接下來(lái)就是Subscriber進(jìn)行封裝了。
封裝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代表服務(wù)器返回成功的數(shù)據(jù) if (((BaseBean)t).getCode() == 1) { //成功后返回data數(shù)據(jù)進(jìn)行處理即可 onSuccess((T) ((BaseBean) t).getData()); }else { //處理服務(wù)器返回錯(cuò)誤code } } @Override public void onComplete() { finishLoading(); } @Override public void onError(Throwable t) { finishLoading(); //處理網(wǎng)絡(luò)異常 Log.d("TAG","=========" + t); } protected abstract void onSuccess(T t); protected abstract void showLoading(); protected abstract void finishLoading(); }
如上所示,我們根據(jù)服務(wù)端返回的code判斷是否成功,將data數(shù)據(jù)傳出去。服務(wù)器返回的錯(cuò)誤碼和網(wǎng)絡(luò)請(qǐng)求錯(cuò)誤我們都可以統(tǒng)一在這里進(jìn)行處理。然后我們?cè)偃y(cè)試接口。
測(cè)試
HttpRequest.getApi().province() .compose(new SchedulersHelper()) .subscribe(new MySubscriber() { @Override protected void onSuccess(Object o) { } @Override protected void showLoading() { } @Override protected void finishLoading() { } });
可以的看到操作流程已經(jīng)變的很簡(jiǎn)單了,對(duì)于showLoading()
和finishLoading()
這兩個(gè)方法我們可以不需要放在這里面,這個(gè)是我方便測(cè)試便將其寫在里面了。
結(jié)束
這是一個(gè)很簡(jiǎn)單封裝過(guò)程,沒(méi)有用到太多復(fù)雜的邏輯。比較通俗易懂,封裝的完善度可能不是很高,大家可以當(dāng)作一個(gè)參考,用自己的理解,更好的去封裝它。之前有寫過(guò)一篇簡(jiǎn)單的MVP基類,這個(gè)封裝過(guò)程我便將它放在了上一篇的項(xiàng)目中。構(gòu)成了一個(gè)簡(jiǎn)單易懂易上手的:RxJava + Retrofit + MVP的小Demo,放在了GitHub上,大家可以查看RxRetrofitMvp。如果你覺(jué)對(duì)你有幫助的話請(qǐng),希望給個(gè)star哦,哈哈哈!
到此這篇關(guān)于Android RxJava與Retrofit結(jié)合使用詳解的文章就介紹到這了,更多相關(guān)Android RxJava與Retrofit內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android ImageView 的幾點(diǎn)經(jīng)驗(yàn)總結(jié)
本篇文章是對(duì)android中ImageView的使用技巧進(jìn)行了幾點(diǎn)經(jīng)驗(yàn)總結(jié),需要的朋友參考下2013-06-06Android實(shí)現(xiàn)自動(dòng)填充短信驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)自動(dòng)填充短信驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Android 中 requestWindowFeature()的應(yīng)用
本文主要介紹 Android requestWindowFeature()方法,這里對(duì) requestWindowFeature()方法進(jìn)行詳解,對(duì)應(yīng)用程序窗體顯示狀態(tài)的操作有進(jìn)一步了解,希望能幫助有需要的小伙伴2016-07-07Flutter彈性布局Flex水平排列Row垂直排列Column使用示例
這篇文章主要為大家介紹了Flutter彈性布局Flex水平排列Row垂直排列Column使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Android 動(dòng)態(tài)顯示和隱藏狀態(tài)欄詳解及實(shí)例
這篇文章主要介紹了Android 動(dòng)態(tài)顯示和隱藏狀態(tài)欄的相關(guān)資料,需要的朋友可以參考下2017-06-06Android開(kāi)發(fā)之拖動(dòng)條/滑動(dòng)條控件、星級(jí)評(píng)分控件功能的實(shí)例代碼
這篇文章主要介紹了Android開(kāi)發(fā)之拖動(dòng)條/滑動(dòng)條控件、星級(jí)評(píng)分控件功能的實(shí)例代碼,需要的朋友可以參考下2019-05-05Android編程之退出整個(gè)應(yīng)用程序的方法
這篇文章主要介紹了Android編程之退出整個(gè)應(yīng)用程序的方法,實(shí)例分析了Android直接關(guān)閉所有的Acitivity并退出應(yīng)用程序的實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-12-12Android高級(jí)UI特效仿直播點(diǎn)贊動(dòng)畫效果
這篇文章主要介紹了Android高級(jí)UI特效仿直播點(diǎn)贊動(dòng)畫效果,最近比較火的抖音快手直播視頻都有這樣的效果,下面腳本之家小編給大家?guī)?lái)android 仿直播點(diǎn)贊效果的實(shí)現(xiàn)代碼,需要的朋友參考下吧2018-03-03Android高性能日志寫入方案的實(shí)現(xiàn)
這篇文章主要給大家介紹了關(guān)于Android高性能日志寫入方案的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01