Retrofit與Rxjava封裝終結(jié)者(二)原理解析

如果沒有了解過基本用法的,可以先看一下上篇博客
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));
    }
  1. 很明顯,如果直接復(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個類

  1. RxRequest:統(tǒng)一配置Observable,包括是否緩存,生命周期統(tǒng)一管理
  2. RxSubscriber:可以統(tǒng)一處理加載進度條,回調(diào)網(wǎng)絡(luò)請求結(jié)果
  3. 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ā)送請求

框架下載地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位,與響應(yīng)式編程作為結(jié)合使用的,對什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,983評論 0 10
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,045評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,564評論 19 139
  • http://blog.csdn.net/yyh352091626/article/details/5330472...
    奈何心善閱讀 3,650評論 0 0
  • 不是不想念,只是那又怎么樣呢。 夢見你的臉,只是不再代表眷念。 一個人,仍會感覺時間狹窄擁擠。快得慢一點,深得淺一...
    一枚小番茄閱讀 259評論 0 0

友情鏈接更多精彩內(nèi)容