在Retrofit和RxJava配合使用時(shí)靶剑,我們會(huì)在構(gòu)建Retrofit對象時(shí)加上這樣一句話:
addCallAdapterFactory(RxJavaCallAdapterFactory.create())
這樣我們就可以從service的方法中獲取到observable對象了矿筝。
public interface MyService {
@GET("user/me")
Observable<User> getUser();
}
其實(shí)RxJavaCallAdapterFactory使用RxJava創(chuàng)建observables時(shí)珍德,支持三種不同的Observable參數(shù)配置尉剩。
- Observable<User>,直接使用body灾挨。對于響應(yīng)碼為2XX的邑退,在OnNext方法中直接返回反序列化的body。而非2XX相應(yīng)碼在onError方法中表現(xiàn)為HttpException劳澄,網(wǎng)絡(luò)錯(cuò)誤在OnError方法中表現(xiàn)為IOException地技。
- Observable<Response<User>>,使用Response包裹body秒拔。所有Http請求的響應(yīng)體都可以在OnNext方法中拿到莫矗,不管響應(yīng)碼是否為2XX。而網(wǎng)絡(luò)錯(cuò)誤會(huì)在OnError方法中表現(xiàn)為IOException砂缩。
- Observable<Result<User>>作谚,使用Result包裹body。所有Http請求的響應(yīng)體和網(wǎng)絡(luò)錯(cuò)誤都會(huì)在OnNext方法中庵芭。
由于現(xiàn)在服務(wù)端返回的數(shù)據(jù)類型大都是下面這個(gè)樣子的:
{
"code":"",
"message":"",
"data":{
}
}
"code"為服務(wù)端與客戶端約定的自定義錯(cuò)誤代碼妹懒,”message"為錯(cuò)誤信息,”data”里面才是真正的業(yè)務(wù)邏輯數(shù)據(jù)双吆。
所以對于這種情況就需要定義一個(gè)BodyResponse類來和這樣的數(shù)據(jù)類型相對應(yīng)眨唬,如下:
public class BodyResponse<T> {
private String code;
private String message;
private T data;
//getter and setter
}
如果data里面的數(shù)據(jù)為列表的話,使用后面兩種方法的話伊诵,observable就會(huì)寫成Observable<Response<BodyResponse<List<User>>>>或者Observable<Result<BodyResponse<List<User>>>>,不知道你們感覺如何单绑,反正我是感覺整個(gè)人都不好了。所以我會(huì)使用第一種寫法曹宴,相信這也是大部分人的寫法搂橙。
那么使用第一種方式的話,我們的Observable就會(huì)寫成Observable<BodyResponse<User>>笛坦。那么在響應(yīng)碼非2XX的情況下区转,我們就可以在onError方法中來進(jìn)行錯(cuò)誤處理了。
observer
.subscribe(new Subscriber<User>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable throwable) {
BodyResponse errBody = ErrorHandler.handle(throwable);
// do something with code or message
}
@Override
public void onNext(User user) {
}
});
ErrorHandler
public class ErrorHandler {
public static BodyResponse handle(Throwable throwable) {
if (throwable instanceof HttpException) {
HttpException error = (HttpException) throwable;
try {
return new Gson().fromJson(error.response().errorBody().string(),
BodyResponse.class);
} catch (IOException e) {
e.printStackTrace();
}
} else {
throwable.printStackTrace();
}
return null;
}
}
是不是很方便呢版扩,很簡單呢废离?