1. 程式人生 > >3、RxJava2 & Retrofit2 封裝實踐 請求與響應的重度封裝

3、RxJava2 & Retrofit2 封裝實踐 請求與響應的重度封裝

東西不多,甚至說很少,目的並不是把網路請求封裝的多麼好,功能多麼全,而是記錄下自己的思路。希望無意中路過的同學看完之後能有些許收穫!

請求前驅 HTTPServiceWrapper
響應後驅 HTTPCallbackWrapper

1、HTTPCENTER

因為HTTPServiceWrapper的出現,HTTPCENTER又要增加東西了~

    /**
     * 獲取ServiceWrapper單例
     * @return
     */
    public static HTTPServiceWrapper getWrapper() {
        return
ServiceWrapperHoler.serviceWrapper; } private static class ServiceWrapperHoler { static HTTPServiceWrapper serviceWrapper = new HTTPServiceWrapper(); }

2、HTTPServiceWrapper

請求前驅:我亂叫的。

程式碼

/**
 * @author Lwang
 * @time 2017/4/26.
 */

public class HTTPServiceWrapper {
    public
static HTTPService dmService = HTTPCenter.getService(HTTPCenter.SERVICE); public static HTTPService toyService = HTTPCenter.getService(HTTPCenter.TOYS_SERVICE); public void heart(HTTPCallbackWrapper<Heart,DMResponse> httpCallbackWrapper) { dmService.heart().map(new Function<Heart, Heart>() { @Override
public Heart apply(@NonNull Heart heart) throws Exception { return heart; } }).compose(httpCallbackWrapper.transformer()).subscribe(httpCallbackWrapper.get()); } public void toys(int offset,int limit,HTTPCallbackWrapper<TimeLineModel,TOYResponse> httpCallbackWrapper) { toyService.requestRecommendTimeLine(offset,limit).map(new Function<TimeLineModel, TimeLineModel>() { @Override public TimeLineModel apply(@NonNull TimeLineModel timeLineModel) throws Exception { /** * 此處還可以取出(例如:登陸資訊)另行儲存 * token * secret */ return timeLineModel; } }).compose(httpCallbackWrapper.transformer()).subscribe(httpCallbackWrapper.get()); } }

把請求時候需要做的瑣碎的操作放在了這個包裝類裡,傳送請求時,只需呼叫HTTPServiceWrapper中的方法即可。

例如:HTTPCenter.getWrapper().toys(0,20,httpCallbackWrapper);

3、HTTPCallbackWrapper 敲黑板!重點!

響應後驅 : 我亂叫的,同時也是重點!
既然是包裝類,那麼肯定就會有HTTPCallback,否則包裝什麼?

/**
 * @author Lwang
 * @time 2017/4/26.
 */

public class HTTPCallBack<T, M> {
    /**
     * 請求開始
     */
    public void onStart() {
    }

    public void onSuccess(T success) {
    }

    /**
     * 處理由伺服器發起的錯誤
     * 401
     * 500 ...
     *
     * @param httpResponse
     */
    public void onFail(M httpResponse) {
    };

    /**
     * 處理異常
     *
     * @param e
     */
    public void onError(Throwable e) {
    };
}

HTTPCallback的泛型

HTTPCallback有兩個泛型<T,M>
T為請求成功的泛型。
M為出現錯誤時的泛型。(為了適應多個Host的情況)

HTTPCallbackWrapper程式碼

/**
 * @author Lwang
 * @time 2017/4/26.
 */

public class HTTPCallbackWrapper<T, M> {
    private RxAppCompatActivity activity;
    private RxFragment fragment;
    private HTTPCallBack<T, M> callBack;
    private Class clazz;
    protected Gson gson = new Gson();

    public HTTPCallbackWrapper(RxAppCompatActivity activity, HTTPCallBack<T, M> callBack) {
        this.activity = activity;
        this.callBack = callBack;
    }

    public HTTPCallbackWrapper(RxFragment fragment, HTTPCallBack<T, M> callBack) {
        this.fragment = fragment;
        this.callBack = callBack;
    }

    public Observer get() {
        return new Observer<T>() {

            @Override
            public void onError(Throwable e) {
                try {
                    if (callBack != null && e != null) {
                        if (e instanceof HttpException) {
                            int errorCode = ((HttpException) e).response().code();
                            switch (errorCode) {
                                case 401:
                                    M response = gson.fromJson("",getClz());
                                    callBack.onFail(response);
                                    break;
                                case 500:
                                    break;
                                default:
                            }
                        } else {
                            //error
                            callBack.onError(e);
                        }
                    } else {
                        //error
                        if (callBack != null)
                            callBack.onError(e);
                    }
                } catch (Exception e1) {
                    //error
                    if (callBack != null)
                        callBack.onError(e);
                }
            }

            @Override
            public void onComplete() {

            }


            @Override
            public void onSubscribe(Disposable d) {
                if (callBack != null)
                    callBack.onStart();
            }

            @Override
            public void onNext(T o) {
                if (callBack != null)
                    callBack.onSuccess(o);
            }
        };
    }

    public <T> ObservableTransformer<T, T> transformer() {
        do {

            if (activity != null) {
                return getObservableTransformer(activity);
            }
            if (fragment != null) {
                return getObservableTransformer(fragment);
            }

        } while (false);
        return null;
    }

    @android.support.annotation.NonNull
    private <T> ObservableTransformer<T, T> getObservableTransformer(RxAppCompatActivity rxAct) {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
                return upstream.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .compose(rxAct.bindToLifecycle());
            }
        };
    }

    @android.support.annotation.NonNull
    private <T> ObservableTransformer<T, T> getObservableTransformer(RxFragment rxFragment) {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
                return upstream.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .compose(rxFragment.bindToLifecycle());
            }
        };
    }

    /**
     * 通過反射拿到泛型 class
     */
    @SuppressWarnings("unchecked")
    public Class<M> getClz() {
        if (clazz == null) {
            clazz = (Class<M>) (((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        }
        return clazz;
    }

}

建構函式中的RxAppCompatActivityRxFragment

為了支援繫結`RxLifecycle`所以在初始化的時候必須傳遞進來。

get函式

    封裝了`RxJava`中的被觀察者,在`onError`中處理了伺服器發出的錯誤,和`RxJava`丟擲的`Throwable`;

前面說到了`HTTPCallbackWrapper`的兩個泛型。重點在`M`。 

```
M response = gson.fromJson("", getClz());
```

怎麼讓onFail返回多種物件呢?

    之前我想多個類實現一個介面,之後讓`onFail`的引數為此介面,後來想到,如果這樣做,呼叫`onFail`的時候得到的是介面物件,還需要根據`host`來確定物件型別,這樣就違背了我的初衷。

所以我想到了繼續用泛型,用泛型就涉及到一個問題。

怎麼得到泛型的class

完美解決問題,感興趣的同學可以查一下反射相關的。
    /**
     * 通過反射拿到泛型 class
     */
    @SuppressWarnings("unchecked")
    public Class<M> getClz() {
        if (clazz == null) {
            clazz = (Class<M>) (((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        }
        return clazz;
    }

封裝RxJava的轉換ObservableTransformertransformer函式)

執行緒切換和RxLifecycle的繫結生命週期每次都會出鏡,當然要封裝起來啦,我還能怎麼辦。。。

配合MVP食用,口感更佳哦~