1.TransFormer的區別
在使用 Retrofit 和 Rxjava 處理網絡流程時,一般會統一處理結果
BaseModel.java
public class BaseModel<T> {
public String code;
public String message;
public T result;
public boolean success(){
return code.equals("0");
}
}
接口返回的數據是這樣的結構,code 爲 0 時纔是正常,實際 javabean 數據在 result 中,那麼希望在數據到達 presenter 之前就處理好請求結果是正確的數據還是錯誤的數據,在Rxjava1.0時一般是這樣的:
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
public class RxHelper {
/**
* 統一處理結果
*
* @param <T>
* @return
*/
public static <T> Observable.Transformer<BaseModel<T>, T> handleResult() {
return new Observable.Transformer<BaseModel<T>, T>() {
@Override
public Observable<T> call(Observable<BaseModel<T>> tObservable) {
return tObservable.flatMap(new Func1<BaseModel<T>, Observable<T>>() {
@Override
public Observable<T> call(BaseModel<T> result) {
if (result.success()) {
return createData(result.result);
} else {
return Observable.error(new ServerException(result.message));
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
};
}
private static <T> Observable<T> createData(final T data) {
return Observable.create(new Observable.OnSubscribe<T>() {
@Override
public void call(Subscriber<? super T> subscriber) {
try {
subscriber.onNext(data);
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}
});
}
}
Api.java
@POST("/contact/update")
Observable<BaseModel<Contact>> update(
@Query("accountId") String accountId,
@Query("userId") String userId);
presenter裏使用時如下:
RetrofitFactory.getApi().check("1","1")
.compose(RxHelper.<Contact>handleResult())
.subscribe();
這樣當數據獲取到之後就會在 handleResult 方法裏先統一判斷結果,並順便設置一下通用的網絡請求線程切換;
如果在 Rxjava2.0 裏,handleResult 方法如下:
public class RxHelper {
/**
* 統一處理結果
*
* @param <T>
* @return
*/
public static <T> ObservableTransformer<BaseModel<T>, T> handleResult() {
return new ObservableTransformer<BaseModel<T>, T>() {
@Override
public ObservableSource<T> apply(Observable<BaseModel<T>> upstream) {
return upstream.flatMap(new Function<BaseModel<T>, ObservableSource<T>>() {
@Override
public ObservableSource<T> apply(BaseModel<T> tBaseModel) throws Exception {
if (tBaseModel.success()) {
return createData(tBaseModel.data);
}
return Observable.error(new ServerException(tBaseModel.msg));
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
};
}
private static <T> ObservableSource<T> createData(final T data) {
return Observable.create(new ObservableOnSubscribe<T>() {
@Override
public void subscribe(ObservableEmitter<T> e) {
try {
e.onNext(data);
e.onComplete();
} catch (Exception e1) {
e.onError(e1);
}
}
});
}
public static <T> FlowableTransformer<GankHttpResponse<T>, T> handleResult() { //compose判斷結果
return new FlowableTransformer<GankHttpResponse<T>, T>() {
@Override
public Flowable<T> apply(Flowable<GankHttpResponse<T>> httpResponseFlowable) {
return httpResponseFlowable.flatMap(new Function<GankHttpResponse<T>, Flowable<T>>() {
@Override
public Flowable<T> apply(GankHttpResponse<T> tGankHttpResponse) {
if(!tGankHttpResponse.getError()) {
return createData(tGankHttpResponse.getResults());
} else {
return Flowable.error(new ApiException("服務器返回error"));
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
};
}
public static <T> Flowable<T> createData(final T t) {
return Flowable.create(new FlowableOnSubscribe<T>() {
@Override
public void subscribe(FlowableEmitter<T> emitter) throws Exception {
try {
emitter.onNext(t);
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
}
}, BackpressureStrategy.BUFFER);
}
}
上面代碼裏列出了兩種情況,因爲 Rxjava2.0 裏有Observable 和 Flowable,那麼Transformer 也要用與之對應的;
2.Subscribe 的區別
前面只是判斷數據是否正常取到的統一處理,當數據獲取到之後,希望再統一處理一些例如彈窗提示一類的邏輯,這時就在觀察者裏做統一處理了,Rxjava1.0處理如下:
import rx.Subscriber;
public abstract class RxSubscribe<T> extends Subscriber<T> {
@Override
public void onCompleted() {
}
@Override
public void onNext(T t) {
_onNext(t);
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
// 錯誤處理
if (!AppUtils.isNetworkAvailable()) {
_onError(mContext.getResources().getString(R.string.toast_text1));
} else if (e instanceof ServerException) {
_onError(e.getMessage());
} else {
_onError(mContext.getResources().getString(R.string.toast_text2) + e.getMessage());
}
}
protected abstract void _onNext(T t);
protected abstract void _onError(String message);
}
錯誤信息在這裏統一判斷處理,還有例如要在處理數據之前先緩存,就可以在onNext()裏直接統一處理,使用時如下;
RetrofitFactory.getApi().check("1", "1")
.compose(RxHelper.<Contact>handleResult())
.subscribe(new RxSubscribe<Contact>(mContext) {
@Override
protected void _onNext(Contact result) {
}
@Override
protected void _onError(String message) {
ToastUtils.showT(message);
}
});
Rxjava2.0 分 Observable 和 Flowable,如果接口返回的是 Observable,這裏要用 DisposableObserver:
import io.reactivex.observers.DisposableObserver;
public abstract class RxSubscribe<T> extends DisposableObserver<T> {
@Override
public void onNext(T t) {
_onNext(t);
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
if (!AppUtils.isNetworkConnected()) {
_onError("網絡不可用");
} else if (e instanceof ServerException) {
_onError(e.getMessage());
} else {
_onError("未知錯誤");
}
}
@Override
public void onComplete() {
}
protected abstract void _onNext(T t);
protected abstract void _onError(String message);
}
如果返回的是 Flowable,這裏要換成繼承 ResourceSubscriber,具體使用如下:
dataManager.appcategory()
.compose(RxHelper.<List<AppCatetory>>handleResult())
.subscribeWith(new RxSubscribe<List<AppCatetory>>() {
@Override
protected void _onNext(List<AppCatetory> appCatetories) {
Logger.e(GsonUtils.toJson(appCatetories));
}
@Override
protected void _onError(String message) {
}
})
3.subscribeWith 和 subscribe
用 subscribe 時,參數只能傳 Rxjava自帶的 Consumer 纔會返回 Disposable,如想傳上面這個自定義的觀察者並且還要返回Disposable,需要用 subscribeWith;這個Disposable 常用來作取消請求使用:
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
/**
* Created by Aislli on 2016/3/17.
*/
public class BasePresenter<V extends IBaseView> implements IBasePresenter{
protected V mView;
protected CompositeDisposable mCompositeDisposable;
protected void addSubscribe(Disposable subscription) {
if (mCompositeDisposable == null) {
mCompositeDisposable = new CompositeDisposable();
}
mCompositeDisposable.add(subscription);
}
protected void unSubscribe() {
if (mCompositeDisposable != null) {
mCompositeDisposable.clear();
}
}
public BasePresenter(V view) {
this.mView = view;
}
@Override
public void destroy() {
this.mView = null;
unSubscribe();
}
}
子類裏把網絡請求的 Disposable 添加到CompositeDisposable,presenter對應的 Activity 關閉時,調用presenter 的destroy 方法取消請求:
addSubscribe(dataManager.appcategory()
.compose(RxHelper.<List<AppCatetory>>handleResult())
.subscribeWith(new RxSubscribe<List<AppCatetory>>() {
@Override
protected void _onNext(List<AppCatetory> appCatetories) {
Logger.e(GsonUtils.toJson(appCatetories));
}
@Override
protected void _onError(String message) {
}
}));