Android?RxJava與Retrofit結(jié)合使用詳解
如今RxJava和Retrofit的結(jié)合使用估計(jì)已經(jīng)相當(dāng)普遍了,自己工作中也是一直都在使用。在使用的過程中我們都會對其進(jìn)行封裝使用,GitHub上也有很多封裝好的項(xiàng)目可以直接拿來使用,其實(shí)對于開源框架的二次封裝有時(shí)候針對不同的業(yè)務(wù)邏輯封裝的過程中也多多少少有些不同,建議還是自己動手去封裝使用。這樣不僅提升自己對原框架的理解,還可以提高自己的封裝能力。在工作過程中如需要改動便更加容易入手。好了,廢話不多說,這里做了一個簡單的樣本供大家參考。
添加依賴
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'
添加依賴本并不想多說,我想大家都知道,但是對于剛接觸這些知識的時(shí)候我想有沒有人在看網(wǎng)上的文章時(shí)會覺得有些依賴是在哪找到并添加的呢?例如:com.squareup.retrofit2:converter-gson:2.3.0我們要添加一個GsonConverter的依賴。對于剛接觸這些知識和不經(jīng)常逛GitHub的人來說會不會一臉懵逼呢?不管會不會,反正我第一次接觸的時(shí)候確實(shí)懵逼了下。這里給那些懵逼過的人提示下,我們可以通過打開GitHub上項(xiàng)目的子文件查看到相應(yīng)的依賴。比如GitHub上Retrofit項(xiàng)目中:retrofit/retrofit-converters/gson/這個路徑下就可以查看到相應(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;
}
}這里我們可以看到添加了兩個攔截器:日志攔截器和網(wǎng)絡(luò)請求Header攔截器,我們都知道對于Retrofit我們是可以直接通過GsonConverter轉(zhuǎn)換成實(shí)體類的,但有的時(shí)候我們又想去獲取它的json數(shù)據(jù)進(jìn)行查看,這個時(shí)候我們就可以通過添加日志攔截器實(shí)現(xiàn),但一定要給它設(shè)置setLevel方法,設(shè)置不同的屬性打印出來的數(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。這個時(shí)候我們就需要對其進(jìn)行二次處理了,我們可以寫一個基類:
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中的不確定格式的數(shù)據(jù),這里用一個獲取全國所有省的數(shù)據(jù)接口進(jìn)行測試:
public interface ApiService {
//獲取省列表
@GET("common/areas")
Flowable<BaseBean<List<Province>>> province();
}
實(shí)體類封裝好后我們可以進(jìn)行一下測試:
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() {
}
});
}
通過上面的代碼我們不難看出這是經(jīng)過封裝后的效果,但是我們會發(fā)現(xiàn)這樣的請求我們難道每次都要去添加調(diào)度器和重寫Subscriber的幾個方法嗎?那豈不還是很繁瑣。是的,接下來我們就對這些進(jìn)行封裝。
使用compose操作符
public class SchedulersHelper implements FlowableTransformer{
@Override
public Publisher apply(Flowable upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}
使用compose操作符可以直接對當(dāng)前Flowable進(jìn)行操作,所以我們自然可以把切換線程的操作加入這里。接下來就是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ù)器返回錯誤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ù)器返回的錯誤碼和網(wǎng)絡(luò)請求錯誤我們都可以統(tǒng)一在這里進(jìn)行處理。然后我們再去測試接口。
測試
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)變的很簡單了,對于showLoading()和finishLoading()這兩個方法我們可以不需要放在這里面,這個是我方便測試便將其寫在里面了。
結(jié)束
這是一個很簡單封裝過程,沒有用到太多復(fù)雜的邏輯。比較通俗易懂,封裝的完善度可能不是很高,大家可以當(dāng)作一個參考,用自己的理解,更好的去封裝它。之前有寫過一篇簡單的MVP基類,這個封裝過程我便將它放在了上一篇的項(xiàng)目中。構(gòu)成了一個簡單易懂易上手的:RxJava + Retrofit + MVP的小Demo,放在了GitHub上,大家可以查看RxRetrofitMvp。如果你覺對你有幫助的話請,希望給個star哦,哈哈哈!
到此這篇關(guān)于Android RxJava與Retrofit結(jié)合使用詳解的文章就介紹到這了,更多相關(guān)Android RxJava與Retrofit內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android開發(fā)中requestfocus()無效的原因及解決辦法
這篇文章主要介紹了Android開發(fā)中requestfocus()無效的原因及解決辦法,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08
Android自定義View實(shí)現(xiàn)價(jià)格區(qū)間選擇控件
這篇文章主要為大家詳細(xì)介紹了Android如何利用自定義View實(shí)現(xiàn)價(jià)格區(qū)間選擇控件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-11-11
Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄
通常手機(jī)通訊錄都會有索引欄,這篇文章主要介紹了Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄,現(xiàn)在分享給大家。2016-10-10
Kotlin實(shí)現(xiàn)在類里面創(chuàng)建main函數(shù)
這篇文章主要介紹了Kotlin實(shí)現(xiàn)在類里面創(chuàng)建main函數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android Studio 3.6 layout文件text模式切換問題
這篇文章主要介紹了Android Studio 3.6 layout文件text模式切換問,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
Android實(shí)現(xiàn)動態(tài)圓環(huán)的圖片頭像控件
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶有動態(tài)圓環(huán)的圓形圖片控件DynamicAvatarView的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
android 使用kotlin 實(shí)現(xiàn)點(diǎn)擊更換全局語言(中日英切換)
這篇文章主要介紹了android kotlin 點(diǎn)擊更換全局語言的實(shí)現(xiàn)方法,這里主要介紹中日英切換,需要的朋友可以參考下2019-11-11

