如果沒有了解過基本用法的,可以先看一下上篇博客
Retrofit與Rxjava封裝終結(jié)者(一)基本用法,先看一下封裝之前的代碼,
Map<String, String> map = new HashMap<>();
map.put("_t", PrefUtils.getString(mContext, "token", ""));
RxRequest.getInstance()
.getProxy(RxUrl.class)
.getServiceType(map)
.subscribeOn(Schedulers.io())
.compose(bindToLifecycle())//綁定生命周期
.compose(bindUntilEvent(ActivityEvent.DESTROY))//Destroy時銷毀
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ArrayList<ServiceBean>>() {
@Override
public void onCompleted() {
//TODO 完成的回調(diào)
}
@Override
public void onError(Throwable e) {
//TODO 失敗的回調(diào)
}
@Override
public void onNext(ArrayList<ServiceBean> serviceBeen) {
//TODO 成功的回調(diào)
Log.d(TAG, "onSuccessResult: " + serviceBeen.size());
mBeanList = serviceBeen;
getPeople();
if (isFirstClass) {
isFirstClass = false;
}
}
});
- 代碼重復(fù)太多,而且每次要回調(diào)三個方法,當(dāng)時想著偷懶,只回調(diào)一個方法,向下面這樣寫
.subscribe(new Action1<ArrayList<ServiceBean>>() {
@Override
public void call(ArrayList<ServiceBean> serviceBeen) {
//TODO 成功的回調(diào)
Log.d(TAG, "onSuccessResult: " + serviceBeen.size());
mBeanList = serviceBeen;
getPeople();
if (isFirstClass) {
isFirstClass = false;
}
}
});
- 這樣寫會報錯,因為沒有復(fù)寫onError方法,好吧,那就只能向下面這樣寫了
.subscribe(new Action1<ArrayList<ServiceBean>>() {
@Override
public void call(ArrayList<ServiceBean> serviceBeen) {
//TODO 成功的回調(diào)
Log.d(TAG, "onSuccessResult: " + serviceBeen.size());
mBeanList = serviceBeen;
getPeople();
if (isFirstClass) {
isFirstClass = false;
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
//TODO 失敗的回調(diào)
}
});
認真的思考一下,我們想要的是什么
- 生命周期統(tǒng)一管理
- 緩存進行處理,GET請求進行緩存,POST請求不緩存
- 只回調(diào)成功后的結(jié)果,錯誤以及異常統(tǒng)一處理
針對以上3點,對上述請求進行了改進
1.針對生命周期以及多余的代碼,也很好解決,這些都是通過Observable來實現(xiàn)的,所以每次我們創(chuàng)建一個Observable對象之后,統(tǒng)一進行處理
if (observable != null)
observable.compose(subscriber.getActivity().bindToLifecycle())//綁定生命周期
.compose(subscriber.getActivity().bindUntilEvent(ActivityEvent.DESTROY))
.subscribeOn(Schedulers.io())//操作線程
.unsubscribeOn(Schedulers.io())//解綁線程
.observeOn(AndroidSchedulers.mainThread())//回調(diào)線程
.subscribe(subscriber);
2.關(guān)于緩存,我們需要一個標(biāo)記為,因為用戶發(fā)起請求之前我們是不知道是否進行緩存的,所以增加了一個方法getProxy(),通過傳遞布爾值來設(shè)置是否進行緩存
public RxUrl getProxy(boolean isCache) {
RxUrl mRxUrl = null;
if (isCache) {
mRxUrl = getCacheRetrofit().create(RxUrl.class);
} else {
mRxUrl = getRetrofit().create(RxUrl.class);
}
//如果不需要token值失效后自動刷新的需求,此處可以直接返回RxUrl
return (RxUrl) Proxy.newProxyInstance(RxUrl.class.getClassLoader(), new Class<?>[]{RxUrl.class}, new ProxyHandler(mRxUrl, false));
}
- 很明顯,如果直接復(fù)寫Subscriber的成功或者失敗的方法,最少也需要復(fù)寫兩個方法,所以需要把Subcriber單獨抽取出來,只對其成功的方法進行回調(diào),這個時候你可能想到了接口,是的,我最開始也是這么想的,但是如果用接口進行回調(diào)的話就必須復(fù)寫該接口的所有方法,所以并不適合,我們想要的結(jié)果是,成功方法必須回調(diào),失敗方法可以選擇回調(diào)或者不回調(diào),所以這個地方需要用到抽象類,代碼如下:
回調(diào)的抽象類
public abstract class Callback<T> {
public abstract void onSuccess(T t);
public void onError(Throwable e) {
Log.d("net_error---->", e.toString());
}
}
自定義的Subcriber
@SuppressWarnings("unchecked")
public class RxSubscriber<T> extends Subscriber<T> {
private SoftReference<Callback> rxListener;
private SoftReference<RxAppCompatActivity> mActivity;
//構(gòu)造方法傳入當(dāng)前的RxAppCompatActivity和回調(diào)的抽象類
public RxSubscriber(RxAppCompatActivity rxAppCompatActivity, Callback<T> listener) {
this.mActivity = new SoftReference(rxAppCompatActivity);
this.rxListener = new SoftReference(listener);
}
@Override
public void onStart() {
//TODO 可是做一些初始化操作,比如說談一個對話框或者進度條
}
@Override
public void onNext(T t) {
if (rxListener.get() != null) {
rxListener.get().onSuccess(t);
}
}
@Override
public void onCompleted() {
//TODO 請求完成時走此方法
}
@Override
public void onError(Throwable e) {
// TODO 請求發(fā)生錯誤時走此方法
if (rxListener.get() != null) {
rxListener.get().onError(e);
}
}
}
上面寫了比較多,總結(jié)起來就是3個類
- RxRequest:統(tǒng)一配置Observable,包括是否緩存,生命周期統(tǒng)一管理
- RxSubscriber:可以統(tǒng)一處理加載進度條,回調(diào)網(wǎng)絡(luò)請求結(jié)果
- RequestManager:發(fā)送請求
最終的使用方法
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("strDate", "2017-03-25");//構(gòu)造參數(shù)
Observable<OneBean> weather=RxRequest.getInstance().getProxy(false).postData(hashMap);//創(chuàng)建Observable對象
RxSubscriber subscriber = new RxSubscriber(this, new Callback<OneBean>() {
@Override
public void onSuccess(OneBean oneBean) {
tvData.setText(oneBean.getHpEntity().getStrContent());
}
});//創(chuàng)建Rxsubscrber對象
RequestManager.getInstance().sendRequest(weather, subscriber);//發(fā)送請求