Rxjava1和2在網絡封裝時的一些區別

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) {
                 }
             }));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章