基于RxJava Retrofit的網(wǎng)絡(luò)框架(二)

Observable網(wǎng)絡(luò)框架的解耦和復(fù)用

Observer一端的解耦

我們可以看到BaseObserver實(shí)際做了errorcode響應(yīng)削彬,loading控制,對(duì)外接口的定義等工作蚓挤。這幾部分工作集中在一個(gè)類(lèi)中有一定的耦合析砸。我們?cè)O(shè)計(jì)的目標(biāo)是業(yè)務(wù)使用自定義的Observer或者直接使用BaseObserver都很方便,但目前的設(shè)計(jì)業(yè)務(wù)要么使用BaseObserver全部功能扼雏,要么自己從頭定義燃异,擴(kuò)展性不強(qiáng)携狭。
我們可以如下優(yōu)化:

將callback接口化

BaseObserver定義的onSuccess(T)和onFail(boolean isException ,Object object)兩個(gè)抽象方法是完全面向業(yè)務(wù)使用者的』乩可將其抽象為接口:

public interface ObserverCallback <T extends MapiHttpResponse<? extends Serializable>>{

    /**
     * 請(qǐng)求成功
     * @param t
     */
    void onSuccess(T t);

    /**
     * 請(qǐng)求失敗
     * @param isException true:返回Throwable false:返回String(ErrorMsg)
     * @param object
     */
    void onFail(boolean isException ,Object object);

}

化為接口有兩個(gè)作用

  1. 規(guī)范自定義的Observer的回調(diào)接口逛腿。
  2. 可以與其他的網(wǎng)絡(luò)請(qǐng)求調(diào)用方式(callback方式,非observable方式)仅颇,回調(diào)接口上統(tǒng)一鳄逾,降低切換成本。
將loading邏輯和error響應(yīng)邏輯分離

定義LoadingObserver灵莲,其實(shí)現(xiàn)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);
        }
    }

    /**
     * 網(wǎng)絡(luò)請(qǐng)求是否loading顯示
     * @return
     */
    protected boolean isShowProgress(){
        return true;
    }
}

這樣做:
1雕凹、將更為通用的loading邏輯抽離,使其可以被獨(dú)立使用或繼承政冻。
2枚抵、如果app存在不同業(yè)務(wù)線(xiàn),可將error影響單獨(dú)處理(不同業(yè)務(wù)線(xiàn)code定義可能不同)明场,將loadingObserver類(lèi)下沉汽摹,適配多業(yè)務(wù)線(xiàn)情況

BaseObserver代碼如下:
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被分為了三層苦锨,原來(lái)BaseObserver這一層可以由多個(gè)更為具體的Observer來(lái)擴(kuò)展逼泣。每一層都有自己的擴(kuò)展功能趴泌。

ObservableSource一端的解耦

我們看下Observable一端做了哪些事情:

  1. 對(duì)Request 參數(shù)做發(fā)送前處理:組合和加密處理
  2. 返回Response 解密處理,Java實(shí)體化
  3. 返回Response code碼判斷及分類(lèi)

Observable端解耦的目的

  1. 耦合性降低后拉庶,方便后續(xù)的擴(kuò)展和組合
  2. 將公共的嗜憔,不易變化的邏輯下沉

這是最終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());
}
Request請(qǐng)求params參數(shù)組合加密處理放到何處氏仗?

前面一章已經(jīng)提到吉捶,params是通過(guò)HttpRequest類(lèi)中的getURLParam()方法完成。
原因有2點(diǎn)
1皆尔、params定義在HttpRequest中呐舔,在Httprequest類(lèi)中拿最方便。
2慷蠕、組合和加密的過(guò)程如果需要定制珊拼,那么直接在HttpRequest子類(lèi)中就可以,和框架不會(huì)有耦合流炕。

Response解密處理杆麸,Java實(shí)體化,在何處處理浪感?

Response解密處理網(wǎng)上有兩種處理方式,
1饼问、在okhttp里使用interceptor攔截器解密 2影兽、ResponseTransformer中處理。
這兩種方式都有問(wèn)題:
雖然app內(nèi)部一般解密方式不變莱革,但是要適應(yīng)多業(yè)務(wù)線(xiàn)峻堰,或者作為適應(yīng)性更廣的框架來(lái)講,這塊解密邏輯放到框架中顯然耦合性太高盅视。
我們采用的方式是定義接口:

public interface ResponseDecryptHandler {
    String decrypt(String var1) throws IOException;
}

HttpRequest類(lèi)中定義實(shí)現(xiàn)接口捐名,并將這種解密方式作為Convertor設(shè)置給Retrofit,這樣將加密的邏輯耦合轉(zhuǎn)移到了HttpRequest基類(lèi)中

addConverterFactory(SecurityConvertFactory.create(request.responseDecryptHandler()))

對(duì)于JavaBean實(shí)體化闹击,一般都采用fastJson方式镶蹋,這里我們通過(guò)map操作符完成,作為鏈?zhǔn)秸{(diào)用中的一環(huán)出現(xiàn)赏半,替換方便贺归。

.map(new JavaBeanFunc(t))
Response的code解析,在何處處理断箫?

前面提到拂酣,response的code分為了解析和處理兩個(gè)部分,分別放在observable和observer中完成仲义。其中ResponseTransformer是用于解析response的返回值婶熬。
ErrorResumeFunction和ResponseFunction分別是網(wǎng)絡(luò)錯(cuò)誤和業(yè)務(wù)錯(cuò)誤剑勾,網(wǎng)絡(luò)錯(cuò)誤不會(huì)變,業(yè)務(wù)錯(cuò)誤的判斷是可能擴(kuò)展的赵颅。ResponseFunction的實(shí)現(xiàn)是可以多樣的虽另。


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的生成過(guò)程中性含,除了一部分的邏輯放入的Request的接口中用于擴(kuò)展洲赵,其他的功能在Observable的生成過(guò)程中以鏈?zhǔn)秸{(diào)用的方式存在,每個(gè)鏈?zhǔn)秸{(diào)用的功能由一個(gè)類(lèi)承擔(dān)商蕴。這也是rxjava的優(yōu)勢(shì)所在叠萍,在調(diào)用方式上天然地將各部分解耦了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绪商,一起剝皮案震驚了整個(gè)濱河市苛谷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌格郁,老刑警劉巖腹殿,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異例书,居然都是意外死亡锣尉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)决采,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)自沧,“玉大人,你說(shuō)我怎么就攤上這事树瞭∧聪幔” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵晒喷,是天一觀(guān)的道長(zhǎng)孝偎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)凉敲,這世上最難降的妖魔是什么衣盾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮爷抓,結(jié)果婚禮上雨效,老公的妹妹穿的比我還像新娘。我一直安慰自己废赞,他們只是感情好徽龟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著唉地,像睡著了一般据悔。 火紅的嫁衣襯著肌膚如雪传透。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天极颓,我揣著相機(jī)與錄音朱盐,去河邊找鬼。 笑死菠隆,一個(gè)胖子當(dāng)著我的面吹牛兵琳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骇径,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼躯肌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了破衔?” 一聲冷哼從身側(cè)響起清女,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晰筛,沒(méi)想到半個(gè)月后嫡丙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡读第,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年曙博,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怜瞒。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡父泳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盼砍,到底是詐尸還是另有隱情,我是刑警寧澤逝她,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布浇坐,位于F島的核電站,受9級(jí)特大地震影響黔宛,放射性物質(zhì)發(fā)生泄漏近刘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一臀晃、第九天 我趴在偏房一處隱蔽的房頂上張望觉渴。 院中可真熱鬧,春花似錦徽惋、人聲如沸案淋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)踢京。三九已至誉碴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓣距,已是汗流浹背黔帕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹈丸,地道東北人成黄。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逻杖,于是被迫代替她去往敵國(guó)和親奋岁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理弧腥,服務(wù)發(fā)現(xiàn)厦取,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,144評(píng)論 25 707
  • 用兩張圖告訴你管搪,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料虾攻? 從這篇文章中你...
    hw1212閱讀 12,724評(píng)論 2 59
  • 歡迎訪(fǎng)問(wèn)我的博客 JavaScript是單線(xiàn)程執(zhí)行的,代碼是一句一句執(zhí)行的更鲁,而異步任務(wù)霎箍,如定時(shí)器或者動(dòng)畫(huà),會(huì)被壓入...
    驚鴻三世閱讀 831評(píng)論 0 3
  • 表面上不是那個(gè)自己 內(nèi)心里還是不能把你忘記 生于現(xiàn)實(shí)時(shí)不敢不憂(yōu)患 只想把最好的自己呈現(xiàn)給你 有時(shí)無(wú)奈的祈禱你比我過(guò)...
    蟄伏的愛(ài)lby閱讀 189評(píng)論 0 0