OkHttp Interceptor 的迭代遞歸實(shí)現(xiàn)的簡化

OkHttp 的攔截器些己,那一塊的代碼很多,也比較復(fù)雜嘿般,在 debug 的時候好多個類來回跳段标,看的很懵,其實(shí)把整個框架拿出來炉奴,簡化一些之后再看逼庞,就清晰多了。下面就是一個簡化后的瞻赶,為了更容易理解往堡,對應(yīng)的類名還是用了 OkHttp 中的類名,返回的值直接用 String共耍。

  1. 首先是定義一個接口

    public interface Interceptor {
        // 攔截
        String intercept(Chain chain);
         
        interface Chain
             // 分發(fā)
            String proceed(String request);
        }
    }
    
  2. 創(chuàng)建 5 個 interceptor 類分別是:RetryAndFollowUpInterceptor、BridgeInterceptor吨瞎、CacheInterceptor痹兜、ConnectInterceptor、CallServerInterceptor 颤诀,實(shí)現(xiàn) Interceptor 接口字旭,重寫 intercept(Chain chain) 方法,在這個方法里調(diào)用 chain.proceed() 方法

    @Override
    public String intercept(Chain chain) {
        chain.proceed("CacheInterceptor");
        System.out.println("CacheInterceptor");
        return "CacheInterceptor";
    }
    
  3. 接下來創(chuàng)建一個類 RealInterceptorChain 實(shí)現(xiàn) Chain 接口崖叫,重寫 proceed() 方法遗淳,在該方法里遍歷 interceptor,并調(diào)用 interceptor.intercept() 方法

    RealInterceptorChain next = new RealInterceptorChain(index + 1,interceptors);
    
    Interceptor interceptor = interceptors.get(index);
    
    System.out.println("遍歷 interceptor 的值:第" + (index + 1) + "個 interceptor:");
    System.out.println("RealInterceptor:" + interceptor.getClass().getName());
    // 在 interceptor 的 intercept 方法里需要用到 Chain 對象心傀,所以在每次取出 interceptor 對象的時候屈暗,也要重新創(chuàng)建一個 Chain 對象
    String intercept = interceptor.intercept(next);
    

    注:實(shí)現(xiàn) Chain 的類只有 RealInterceptorChain 這一個類。

  4. 添加 interceptors脂男,然后開始迭代

    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.add(new RetryAndFollowUpInterceptor());
    interceptors.add(new BridgeInterceptor());
    interceptors.add(new CacheInterceptor());
    interceptors.add(new ConnectInterceptor());
    interceptors.add(new CallServerInterceptor());
    
    RealInterceptorChain chain = new RealInterceptorChain(0,interceptors);
    
    String real_call = chain.proceed("real call");
    

    注:chain.proceed() 迭代的開始养叛。

  5. 當(dāng)執(zhí)行完chain.proceed() 方法后就會進(jìn)入到它的實(shí)現(xiàn)類中去,也就是 RealInterceptorChain 類中的 proceed() 方法宰翅,也就是第三步中的代碼里弃甥,在這個方法里核心的一句: interceptor.intercept(next),執(zhí)行這一句就會進(jìn)入到 interceptor 對應(yīng)的實(shí)現(xiàn)類中去汁讼,這時的實(shí)現(xiàn)類是 RetryAndFollowUpInterceptor淆攻,也就是它的 intercept() 方法中去阔墩,也就是第二步中的代碼,在這個方法最核心的一句 :chain.proceed("CacheInterceptor")瓶珊,執(zhí)行這一句啸箫,又會回到第三步,創(chuàng)建一個新的 RealInterceptorChain艰毒、取出下一個 interceptor筐高,開始又一輪的迭代。

  6. 當(dāng)執(zhí)行到最后一個 interceptor 時丑瞧,這里對應(yīng)的是 CallServerInterceptor柑土,在它的 intercept 方法中沒有再執(zhí)行 chain.proceed() 方法,遍歷結(jié)束绊汹,繼續(xù)后面的操作稽屏。

    @Override
    public String intercept(Chain chain) {
        System.out.println("interceptors 中最后一個 interceptor, intercept 中不再執(zhí)行 chain,遍歷結(jié)束西乖,開始返回值");
        System.out.println("CallServerInterceptor");
        return "返回的值:CallServerInterceptor";
    }
    
  7. 結(jié)束遍歷之后狐榔,開始返回數(shù)據(jù),返回的時候從最后一個 interceptor 開始返回获雕,依次返回到第一個薄腻,最后返回到最初調(diào)用的地方。

全部文件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末届案,一起剝皮案震驚了整個濱河市庵楷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌楣颠,老刑警劉巖尽纽,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異童漩,居然都是意外死亡弄贿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門矫膨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來差凹,“玉大人,你說我怎么就攤上這事侧馅≈狈埽” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵施禾,是天一觀的道長脚线。 經(jīng)常有香客問我,道長弥搞,這世上最難降的妖魔是什么邮绿? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任渠旁,我火速辦了婚禮,結(jié)果婚禮上船逮,老公的妹妹穿的比我還像新娘顾腊。我一直安慰自己,他們只是感情好挖胃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布杂靶。 她就那樣靜靜地躺著,像睡著了一般酱鸭。 火紅的嫁衣襯著肌膚如雪吗垮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天凹髓,我揣著相機(jī)與錄音烁登,去河邊找鬼。 笑死蔚舀,一個胖子當(dāng)著我的面吹牛饵沧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赌躺,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼狼牺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了礼患?” 一聲冷哼從身側(cè)響起是钥,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讶泰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拂到,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痪署,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了兄旬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狼犯。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖领铐,靈堂內(nèi)的尸體忽然破棺而出悯森,到底是詐尸還是另有隱情,我是刑警寧澤绪撵,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布瓢姻,位于F島的核電站,受9級特大地震影響音诈,放射性物質(zhì)發(fā)生泄漏幻碱。R本人自食惡果不足惜绎狭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望褥傍。 院中可真熱鬧儡嘶,春花似錦、人聲如沸恍风。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朋贬。三九已至凯楔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兄世,已是汗流浹背啼辣。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留御滩,地道東北人鸥拧。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像削解,于是被迫代替她去往敵國和親富弦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

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

  • 一氛驮、前言 在《OkHttp深入分析——基礎(chǔ)認(rèn)知部分》對 OkHttp 源碼的工程已經(jīng)有一個大致的了解了腕柜,這篇文章里...
    仰簡閱讀 1,037評論 0 4
  • 這篇文章主要講 Android 網(wǎng)絡(luò)請求時所使用到的各個請求庫的關(guān)系,以及 OkHttp3 的介紹矫废。(如理解有誤盏缤,...
    小莊bb閱讀 1,157評論 0 4
  • 緩存的一般思路 下面是我理解的網(wǎng)絡(luò)請求框架的緩存基本實(shí)現(xiàn)。大致的過程是有緩存用緩存的數(shù)據(jù)蓖扑,沒緩存發(fā)起http請求取...
    原件閱讀 2,808評論 3 12
  • 在 Okhttp源碼學(xué)習(xí)一(基本請求流程)中唉铜,只是學(xué)習(xí)了okhttp請求網(wǎng)絡(luò)的一個基本流程,但是最關(guān)鍵的點(diǎn)律杠,同步或...
    有興不虛昧閱讀 448評論 0 1
  • 子夜秋雨綿愁長潭流, 誰家玉樓有燭光? 偏偏相思睡不得柜去, 舊字重讀自感傷灰嫉。 門前雙木枝連理, 溪邊鴛鴦自成雙嗓奢, 可憐春...
    柏舟BAEJOU閱讀 430評論 0 1