3、RxJava2 & Retrofit2 封裝實踐 請求與響應的重度封裝
阿新 • • 發佈:2019-01-27
東西不多,甚至說很少,目的並不是把網路請求封裝的多麼好,功能多麼全,而是記錄下自己的思路。希望無意中路過的同學看完之後能有些許收穫!
請求前驅
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;
}
}
建構函式中的RxAppCompatActivity
和RxFragment
為了支援繫結`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
的轉換ObservableTransformer
(transformer
函式)
執行緒切換和RxLifecycle
的繫結生命週期每次都會出鏡,當然要封裝起來啦,我還能怎麼辦。。。
配合MVP
食用,口感更佳哦~