Android RxJava+Retrofit2+RxBinding
本文原創(chuàng)像屋,轉(zhuǎn)載請注明出處掠河。歡迎關(guān)注我的 簡書拍柒。
安利一波我寫的開發(fā)框架:MyScFrame喜歡的話就給個Star
前言:
之前寫了一篇名為Android 手把手教你使用Retrofit2的文章,只是單純并簡單的介紹了下Retrofit2的使用,現(xiàn)在我們把它跟RxJava以及RxBinding關(guān)聯(lián)起來,看看效果如何
添加依賴
RxBinding的依賴比較麻煩,是按控件包區(qū)分的,我這邊只用到了基礎(chǔ)包也就是android.widget.
所以只引入了compile 'com.jakewharton.rxbinding:rxbinding:1.0.0'
//全新網(wǎng)絡(luò)請求框架Rxjava+RxAndroid+ReTrofit2+okHttp3
compile 'com.tamic.novate:novate:1.2.7'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
//日志攔截器
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
compile 'io.reactivex:rxjava:1.2.4'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'org.ligboy.retrofit2:converter-fastjson-android:2.1.0'
//RxBinding
compile 'com.jakewharton.rxbinding:rxbinding:1.0.0'
// compile 'com.jakewharton.rxbinding:rxbinding-support-v4:1.0.0'
// compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:1.0.0'
// compile 'com.jakewharton.rxbinding:rxbinding-design:1.0.0'
// compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:1.0.0'
開始關(guān)聯(lián)
MyRetrofit2Service差異
在使用RxJava之前是這樣的
@POST()
Call<HttpResult<News>> post(@Url String url, @QueryMap Map<String, String> map);
使用了RxJava之后是這樣的
@POST()
Observable<HttpResult<News>> rxPost(@Url String url, @QueryMap Map<String, String> map);
MyRetrofit2調(diào)用方法上的差異
在使用RxJava之前是這樣的
/**
* 異步調(diào)用
*/
public void getEnqueue() {
Call<HttpResult<News>> call = mApi.post(NEWS_URI, params);
call.enqueue(new Callback<HttpResult<News>>() {
@Override
public void onResponse(Call<HttpResult<News>> call, Response<HttpResult<News>> response) {
//處理請求成功
Log.e("OkHttp", "處理成功請求 response = " + response.body().toString());
}
@Override
public void onFailure(Call<HttpResult<News>> call, Throwable t) {
//處理請求失敗
Log.e("OkHttp", "處理失敗請求");
}
});
// cancelCall(call);
}
使用了RxJava之后是這樣的
public void RxJavaGetEnqueue(Subscriber<News> subscriber) {
Observable observable = mApi.rxPost(NEWS_URI, params)
.map(new HttpResultFunc<News>());
toSubscribe(observable, subscriber);
}
private <T> void toSubscribe(Observable<T> o, Subscriber<T> s) {
o.subscribeOn(Schedulers.io())//設(shè)置事件觸發(fā)在非主線程
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())//在主線程處理返回數(shù)據(jù)
.subscribe(s);
}
/**
* 用來統(tǒng)一處理Http的resultCode,并將HttpResult的Data部分剝離出來返回給subscriber
*
* @param <T> Subscriber真正需要的數(shù)據(jù)類型,也就是Data部分的數(shù)據(jù)類型
*/
private class HttpResultFunc<T> implements Func1<HttpResult<T>, T> {
@Override
public T call(HttpResult<T> httpResult) {
Log.e("OkHttp", "HttpResultFunc httpResult = " + httpResult.toString());
if ("200".equals(httpResult.getStatus_code()) && httpResult.isSuccess()) {
return httpResult.getData();
}
throw new ApiException(httpResult.getStatus_code());
}
}
初看代碼量變多了,沒錯,是變多了,但是誰叫他最近比較火呢,而且目前我只是實現(xiàn)比較簡單的場景,還沒發(fā)揮出RxJava的真正功效呢.
這里需要說下HttpResultFunc<T>
方法的作用,好用就好用在這里,這里我是根據(jù)網(wǎng)絡(luò)請求的code跟success兩個參數(shù)判斷是否是成功的,如果是成功返回,那就返回data
,如果是錯誤的話,自己寫了個ApiException
類是用來處理錯誤信息的
/**
* Created by caihan on 2017/1/14.
*/
public class ApiException extends RuntimeException {
public static final int WRONG_1 = 100;
public static final int WRONG_2 = 101;
public ApiException(int resultCode) {
this(getApiExceptionMessage(resultCode));
}
public ApiException(String detailMessage) {
super(detailMessage);
}
/**
* 由于服務(wù)器傳遞過來的錯誤信息直接給用戶看的話猾警,用戶未必能夠理解
* 需要根據(jù)錯誤碼對錯誤信息進(jìn)行一個轉(zhuǎn)換,在顯示給用戶
*
* @param code
* @return
*/
private static String getApiExceptionMessage(int code) {
String message = "";
switch (code) {
case WRONG_1:
message = "錯誤1";
break;
case WRONG_2:
message = "錯誤2";
break;
default:
message = "未知錯誤";
}
return message;
}
}
界面上調(diào)用方式的變化
之前是這樣的
MyRetrofit2.getInstance().getEnqueue();
現(xiàn)在是這樣子的
private void rxGet() {
MyRetrofit2.getInstance().RxJavaGetEnqueue(new Subscriber<News>() {
@Override
public void onCompleted() {
Log.e("OkHttp", "rxGet onCompleted");
}
@Override
public void onError(java.lang.Throwable e) {
Log.e("OkHttp", "rxGet onError e= " + e.toString());
}
@Override
public void onNext(News news) {
Log.e("OkHttp", "rxGet onNext news= " + news.toString());
}
});
}
用RxBinding處理頻繁點(diǎn)擊問題
開發(fā)中大家都會遇到這類問題,用戶不(gui)小(cai)心(xin)點(diǎn)擊了N次Button,導(dǎo)致Button相應(yīng)了N次,之前我是寫了個DoubleClick類,專門處理此類事件,相信大家也都會,現(xiàn)在有了RxBinding,解放了
RxView.clicks(mButton)
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe(new Action1<Void>() {
@Override
public void call(Void o) {
Log.d("OkHttp", "clickAction call");
rxGet();
}
});
throttleFirst()
方法就是處理這種不小心事件,它會把設(shè)置時間內(nèi)的其他響應(yīng)事件過濾掉,怎么樣,是不是很好用呀...其他的控件如何處理我這邊就不寫了,大家感興趣的話可以看看相關(guān)資料
資料
急速開發(fā)系列——RxJava實戰(zhàn)技巧大全
RxBinding詳解: 規(guī)范而強(qiáng)大的安卓UI響應(yīng)式編程
初涉Rx套餐 之RxBinding(讓你的事件流程更清晰)
總結(jié)
響應(yīng)式開發(fā)我也還在摸索當(dāng)中,這里沒做過多的封裝,因為還有很多地方?jīng)]搞懂,最近也是一直在找相關(guān)的資料.如果大家在其他地方看到了一些相關(guān)的優(yōu)秀文章,可以分享給我,謝謝