RxJava練武場是一個rxjava在項目中應用的小系列,包括:java
咱們能夠看到BaseObserver實際作了errorcode響應,loading控制,對外接口的定義等工做。這幾部分工做集中在一個類中有必定的耦合。咱們設計的目標是業務使用自定義的Observer或者直接使用BaseObserver都很方便,但目前的設計業務要麼使用BaseObserver所有功能,要麼本身從頭定義,擴展性不強。 咱們能夠以下優化:api
BaseObserver定義的onSuccess(T)和onFail(boolean isException ,Object object)兩個抽象方法是徹底面向業務使用者的。可將其抽象爲接口:數組
public interface ObserverCallback <T extends MapiHttpResponse<? extends Serializable>>{
/**
* 請求成功
* @param t
*/
void onSuccess(T t);
/**
* 請求失敗
* @param isException true:返回Throwable false:返回String(ErrorMsg)
* @param object
*/
void onFail(boolean isException ,Object object);
}
複製代碼
化爲接口有兩個做用bash
定義LoadingObserver,其實現ObserverCallback接口網絡
public abstract class LoadingObserver<T extends MapiHttpResponse<? extends Serializable>>
implements Observer<T> ,ObserverCallback<T>{
protected BaseContext mBaseContext;
public LoadingObserver(BaseContext baseContext){
mBaseContext = baseContext;
}
@Override
public void onSubscribe(Disposable d) {
if (isShowProgress()) {
showProgress(true);
}
}
@Override
public void onNext(T t) {
if (isShowProgress()) {
showProgress(false);
}
onSuccess(t);
}
@Override
public void onError(Throwable e) {
if (isShowProgress()) {
showProgress(false);
}
}
@Override
public void onComplete() {
if (isShowProgress()) {
showProgress(false);
}
}
protected void showProgress(boolean isShow){
if (mBaseContext != null) {
mBaseContext.showLoading(isShow);
}
}
/**
* 網絡請求是否loading顯示
* @return
*/
protected boolean isShowProgress(){
return true;
}
}
複製代碼
這樣作: 一、將更爲通用的loading邏輯抽離,使其能夠被獨立使用或繼承。 二、若是app存在不一樣業務線,可將error影響單獨處理(不一樣業務線code定義可能不一樣),將loadingObserver類下沉,適配多業務線狀況app
public abstract class MapiObserver<T extends MapiHttpResponse<? extends Serializable>>
extends LoadingObserver<T>{
public MapiObserver(BaseContext baseContext){
super(baseContext);
}
@Override
public void onError(Throwable e) {
super.onError(e);
handleError(e);
}
private void handleError(Throwable e){
//handle error code
}
}
複製代碼
至此,Observer被分爲了三層,原來BaseObserver這一層能夠由多個更爲具體的Observer來擴展。每一層都有本身的擴展功能。框架
咱們看下Observable一端作了哪些事情:ide
Observable端解耦的目的post
這是最終Observable生成的代碼:優化
private static Observable<R> sendRequest(final HttpRequest request,final TypeReference<R> t)
{
return NetHelper.getApiObservable(request)
.map(new JavaBeanFunc(t))
.compose(ResponseTransformer.handleResult())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
複製代碼
前面一章已經提到,params是經過HttpRequest類中的getURLParam()方法完成。 緣由有2點 一、params定義在HttpRequest中,在Httprequest類中拿最方便。 二、組合和加密的過程若是須要定製,那麼直接在HttpRequest子類中就能夠,和框架不會有耦合。
Response解密處理網上有兩種處理方式, 一、在okhttp裏使用interceptor攔截器解密 二、ResponseTransformer中處理。 這兩種方式都有問題: 雖然app內部通常解密方式不變,可是要適應多業務線,或者做爲適應性更廣的框架來說,這塊解密邏輯放到框架中顯然耦合性過高。 咱們採用的方式是定義接口:
public interface ResponseDecryptHandler {
String decrypt(String var1) throws IOException;
}
複製代碼
HttpRequest類中定義實現接口,並將這種解密方式做爲Convertor設置給Retrofit,這樣將加密的邏輯耦合轉移到了HttpRequest基類中
addConverterFactory(SecurityConvertFactory.create(request.responseDecryptHandler()))
複製代碼
對於JavaBean實體化,通常都採用fastJson方式,這裏咱們經過map操做符完成,做爲鏈式調用中的一環出現,替換方便。
.map(new JavaBeanFunc(t))
複製代碼
前面提到,response的code分爲了解析和處理兩個部分,分別放在observable和observer中完成。其中ResponseTransformer是用於解析response的返回值。 ErrorResumeFunction和ResponseFunction分別是網絡錯誤和業務錯誤,網絡錯誤不會變,業務錯誤的判斷是可能擴展的。ResponseFunction的實現是能夠多樣的。
private static Observable<R> sendRequest(final HttpRequest request,final TypeReference<R> t)
{
return NetHelper.getApiObservable(request)
.map(new JavaBeanFunc(t))
.compose(ResponseTransformer.handleResult())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
複製代碼
以上能夠看出Observable的生成過程當中,除了一部分的邏輯放入的Request的接口中用於擴展,其餘的功能在Observable的生成過程當中以鏈式調用的方式存在,每一個鏈式調用的功能由一個類承擔。這也是rxjava的優點所在,在調用方式上自然地將各部分解耦了。