常用網(wǎng)絡(luò)框架

前言

App開發(fā)過(guò)程中必定使用網(wǎng)絡(luò)請(qǐng)求處理各種業(yè)務(wù)數(shù)據(jù)骤竹,使用成熟的網(wǎng)路組件能夠極大提高開發(fā)效率帝牡,實(shí)現(xiàn)業(yè)務(wù)的需求迭代。目前市面上可供選擇的網(wǎng)絡(luò)框架有AndroidAsync蒙揣、Volley靶溜、OkHttp、Retrofit等懒震,在選擇網(wǎng)絡(luò)組件時(shí)必定要考慮每個(gè)框架的特點(diǎn)罩息,依據(jù)自己業(yè)務(wù)合理選擇,先對(duì)這些框架做簡(jiǎn)要的分析比較个扰。

1 原生網(wǎng)絡(luò)請(qǐng)求

1.1 HttpClient

HttpClient是Apache Jakarta Common下的子項(xiàng)目瓷炮,用來(lái)提供高效的、最新的递宅、功能豐富的支持HTTP協(xié)議的客戶端編程工具包娘香,并且它支持HTTP協(xié)議最新的版本和建議。HttpClient已經(jīng)應(yīng)用在很多的項(xiàng)目中办龄,比如Apache Jakarta上很著名的另外兩個(gè)開源項(xiàng)目Cactus和HTMLUnit都使用了HttpClient烘绽。

示例代碼,基于httpclient-4.5.6.jar

public String doPost(String url){
    CloseableHttpClient httpClient = null;
    CloseableHttpResponse response = null;
    String result = "";
    try{
        //通過(guò)默認(rèn)配置創(chuàng)建一個(gè)httpClient實(shí)例
        httpClient = HttpClients.createDefault();
        //創(chuàng)建httpPost遠(yuǎn)程連接實(shí)例
        HttpPost httpPost = new HttpPost(url);
        //httpPost.addHeader("Connection", "keep-alive");
        httpPost.addHeader("Content-Type", "application/json");
        httpPost.addHeader("Accept", "application/json");
        //配置請(qǐng)求參數(shù)
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(35000) //設(shè)置連接主機(jī)服務(wù)超時(shí)時(shí)間
                .setConnectionRequestTimeout(35000)//設(shè)置請(qǐng)求超時(shí)時(shí)間
                .setSocketTimeout(60000)//設(shè)置數(shù)據(jù)讀取超時(shí)時(shí)間
                .build();
        //為httpPost實(shí)例設(shè)置配置
        httpPost.setConfig(requestConfig);
        //創(chuàng)建請(qǐng)求內(nèi)容
        String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
        StringEntity entity = new StringEntity(jsonStr);
        httpPost.setEntity(entity);
        //執(zhí)行post請(qǐng)求得到返回對(duì)象
        response = httpClient.execute(httpPost);
        //通過(guò)返回對(duì)象獲取返回?cái)?shù)據(jù)
        HttpEntity entity = response.getEntity();
        //通過(guò)EntityUtils中的toString方法將結(jié)果轉(zhuǎn)換為字符串
        result = EntityUtils.toString(entity,"utf-8");
        System.out.println(result);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        //關(guān)閉資源
        if(response != null){
            try {
                response.close();
            }catch (IOException ioe){
                ioe.printStackTrace();
            }
        }
        if(httpClient != null){
            try{
                httpClient.close();
            }catch (IOException ioe){
                ioe.printStackTrace();
            }
        }
    }
    return result;
}
1.2 HttpURLConnection

示例代碼

public String doPost(String URL){
    OutputStreamWriter out = null;
    BufferedReader in = null;
    StringBuilder result = new StringBuilder();
    HttpURLConnection conn = null;
    try{
        URL url = new URL(URL);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        //發(fā)送POST請(qǐng)求必須設(shè)置為true
        conn.setDoOutput(true);
        conn.setDoInput(true);
        //設(shè)置連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(10000);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Accept", "application/json");
        //獲取輸出流
        out = new OutputStreamWriter(conn.getOutputStream());
        String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
        out.write(jsonStr);
        out.flush();
        out.close();
        //取得輸入流土榴,并使用Reader讀取
        if (200 == conn.getResponseCode()){
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null){
                result.append(line);
                System.out.println(line);
            }
        }else{
            System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        try{
            if(out != null){
                out.close();
            }
            if(in != null){
                in.close();
            }
        }catch (IOException ioe){
            ioe.printStackTrace();
        }
    }
    return result.toString();
}

1.3 HttpClient與HttpURLConnection比較

HttpClient-HttpURLConnection.png

2 主流網(wǎng)絡(luò)庫(kù)介紹

2.1 為什么要設(shè)計(jì)網(wǎng)絡(luò)庫(kù)诀姚?

Andorid主線程不允許做耗時(shí)操作响牛,所以在進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí)需要手動(dòng)開啟新線程做任務(wù)玷禽。處理請(qǐng)求時(shí)需要設(shè)置各種網(wǎng)絡(luò)參數(shù)赫段,在網(wǎng)絡(luò)返回時(shí)需要依據(jù)結(jié)果做不同的邏輯判斷,在失敗的情況下須考慮重試機(jī)制矢赁,在成功時(shí)須借助Handler機(jī)制通知UI現(xiàn)場(chǎng)做出變化糯笙,同時(shí)需要考慮結(jié)果的緩存事宜,所有這些都自己實(shí)現(xiàn)會(huì)帶來(lái)工作量的具體提升撩银,而且不能保障其性能和穩(wěn)定性给涕。

目前市面上成熟的網(wǎng)絡(luò)庫(kù)有效的解決了異步請(qǐng)求、線程池额获、緩存等問(wèn)題够庙,提供友好的API,方便使用者調(diào)用抄邀,降低開發(fā)難度耘眨,縮短開發(fā)周期。網(wǎng)絡(luò)組件一般完成如下事項(xiàng):


網(wǎng)絡(luò)組件.png

2.2 主流網(wǎng)絡(luò)庫(kù)對(duì)比

主流網(wǎng)絡(luò)請(qǐng)求庫(kù)對(duì)比.png
2.2.1 Android-Async-Http

目前 HttpClient 已經(jīng)被廢棄境肾,而 android-async-http 是基于 HttpClient 的剔难,我想可能也是因?yàn)檫@個(gè)原因作者放棄維護(hù)。

2.2.2 Volley

VolleyVolley 是 Google 官方出的一套小而巧的異步請(qǐng)求庫(kù)奥喻,該框架封裝的擴(kuò)展性很強(qiáng)偶宫,支持 HttpClient、HttpUrlConnection环鲤,甚至支持 OkHttp纯趋。Volley 里面封裝了 ImageLoader ,對(duì)于簡(jiǎn)單的需求可以使用冷离,對(duì)于稍復(fù)雜點(diǎn)的需求還是需要用到專門的圖片加載框架结闸。Volley 適合數(shù)據(jù)量不大,通信頻繁的網(wǎng)絡(luò)操作酒朵,不支持同步桦锄,不能post大數(shù)據(jù)。

2.2.3 OkHttp

OkHttp 是 Square 公司開源的針對(duì) Java 和 Android 程序蔫耽,封裝的一個(gè)高性能 http 請(qǐng)求庫(kù)结耀,它的職責(zé)跟 HttpUrlConnection 是一樣的,支持 spdy匙铡、http 2.0图甜、websocket 、GZIP鳖眼、HTTP 緩存黑毅、同步與異步,而且 OkHttp 封裝了線程池钦讳,封裝了數(shù)據(jù)轉(zhuǎn)換矿瘦,封裝了參數(shù)使用枕面、錯(cuò)誤處理等,能夠自動(dòng)處理常見的網(wǎng)絡(luò)問(wèn)題缚去,像二次連接潮秘、SSL的握手問(wèn)題。
在Android4.4的源碼中HttpURLConnection已經(jīng)替換成OkHttp實(shí)現(xiàn)了易结,SPDY是Google開發(fā)的基于TCP的傳輸層協(xié)議枕荞,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度搞动,優(yōu)化用戶的網(wǎng)絡(luò)使用體驗(yàn)躏精。OkHttp使用Okio來(lái)大大簡(jiǎn)化數(shù)據(jù)的訪問(wèn)與存儲(chǔ),Okio是一個(gè)增強(qiáng) java.io 和 java.nio的庫(kù)鹦肿。

2.2.4 Retrofit

Retrofit 是 Square 公司出品的默認(rèn)基于 OkHttp 封裝的一套 RESTful 網(wǎng)絡(luò)請(qǐng)求框架玉控,RESTful 是目前流行的一套 api 設(shè)計(jì)的風(fēng)格,并不是標(biāo)準(zhǔn)狮惜。Retrofit簡(jiǎn)化了網(wǎng)絡(luò)請(qǐng)求的流程高诺,提供不同的Json Converter實(shí)現(xiàn),提供RxJava支持碾篡,還有Dagger2比volley解耦更徹底虱而。
關(guān)鍵是想要用好這個(gè)框架,最好是和RxJava聯(lián)用开泽,否者和普通的網(wǎng)絡(luò)框架也沒什么區(qū)別牡拇。

參考資料:

[1] Android探索之HttpURLConnection網(wǎng)絡(luò)請(qǐng)求
[2] Java代碼發(fā)送Http的GET和POST請(qǐng)求
[3] Android開源:主流網(wǎng)絡(luò)請(qǐng)求庫(kù)對(duì)比
[4] Android Http請(qǐng)求框架的選擇
[5] 六款值得推薦的網(wǎng)絡(luò)開源請(qǐng)求框架
[6] Android的開發(fā)之&論網(wǎng)絡(luò)加載框架

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市穆律,隨后出現(xiàn)的幾起案子惠呼,更是在濱河造成了極大的恐慌,老刑警劉巖峦耘,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剔蹋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辅髓,警方通過(guò)查閱死者的電腦和手機(jī)泣崩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)洛口,“玉大人矫付,你說(shuō)我怎么就攤上這事〉谘妫” “怎么了买优?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我杀赢,道長(zhǎng)烘跺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任葵陵,我火速辦了婚禮,結(jié)果婚禮上瞻佛,老公的妹妹穿的比我還像新娘脱篙。我一直安慰自己,他們只是感情好伤柄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布绊困。 她就那樣靜靜地躺著,像睡著了一般适刀。 火紅的嫁衣襯著肌膚如雪秤朗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天笔喉,我揣著相機(jī)與錄音取视,去河邊找鬼。 笑死常挚,一個(gè)胖子當(dāng)著我的面吹牛作谭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奄毡,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼折欠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吼过?” 一聲冷哼從身側(cè)響起锐秦,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盗忱,沒想到半個(gè)月后酱床,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡趟佃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年斤葱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揖闸。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡揍堕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汤纸,到底是詐尸還是另有隱情衩茸,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布贮泞,位于F島的核電站楞慈,受9級(jí)特大地震影響幔烛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜囊蓝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一饿悬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧聚霜,春花似錦狡恬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至姥芥,卻和暖如春兔乞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凉唐。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工庸追, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人台囱。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓锚国,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親玄坦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子血筑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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