OkHttp3 最有營(yíng)養(yǎng)的初級(jí)教程谓罗,快來圍觀吧

一、前言

自從Android4.4開始胯舷,google已經(jīng)開始將源碼中的HttpURLConnection替換為OkHttp桑嘶,而在Android6.0之后的SDK中g(shù)oogle更是移除了對(duì)于HttpClient的支持讨便,而市面上流行的Retrofit同樣是使用OkHttp進(jìn)行再次封裝而來的以政。由此看見學(xué)習(xí)OkHttp的重要性。

本篇文章是以當(dāng)前最新的版本 3.5.0為例(2.0及以上版本版本與3.0以上版本存在較大差異盈蛮,本文不做深入討論抖誉,請(qǐng)自行百度)袒炉,使用Android Stuido作為開發(fā)環(huán)境韧拒,帶領(lǐng)大家簡(jiǎn)單的熟悉OKHttp的使用情況十性。作為《Android網(wǎng)絡(luò)編程》系類文章之一劲适,后面的文章會(huì)圍繞OKHttp3做逐漸深入的探討霞势。這篇文章我們要達(dá)到的目的就是:不深究愕贡,簡(jiǎn)單明了固以,可以直接粘貼復(fù)制憨琳。

二篙螟、使用前的準(zhǔn)備

2.1 官方文檔

要知道學(xué)習(xí)一門新技術(shù)惧所,最好的資料永遠(yuǎn)是官方文檔:
OkHttp官方介紹
github源碼

2.2 Android Studio 配置gradle環(huán)境:

compile 'com.squareup.okhttp3:okhttp:3.5.0'
compile 'com.squareup.okio:okio:1.11.0'

2.3 添加網(wǎng)絡(luò)權(quán)限

不要忘記添加權(quán)限啊纯路,這也是常常被開發(fā)忽略的地方

<uses-permission android:name="android.permission.INTERNET"/>

三驰唬、使用教程

3.1 Http Get

3.1.1 異步的Get

在Http請(qǐng)求中最常見的就是get方法了叫编,在大多數(shù)的使用場(chǎng)景中搓逾,我們使用的都是異步的Get請(qǐng)求霞篡,下面我們就是用OkHttp的異步Get去請(qǐng)求一下百度的首頁端逼。

        // step 1: 創(chuàng)建 OkHttpClient 對(duì)象    
        OkHttpClient okHttpClient = new OkHttpClient();

        // step 2: 創(chuàng)建一個(gè)請(qǐng)求顶滩,不指定請(qǐng)求方法時(shí)默認(rèn)是GET礁鲁。
        Request.Builder requestBuilder = new Request.Builder().url("http://www.baidu.com");
        //可以省略,默認(rèn)是GET請(qǐng)求
        requestBuilder.method("GET",null);

        // step 3:創(chuàng)建 Call 對(duì)象
        Call call = okHttpClient.newCall(requestBuilder.build());

        //step 4: 開始異步請(qǐng)求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // TODO: 17-1-4  請(qǐng)求失敗
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // TODO: 17-1-4 請(qǐng)求成功
                //獲得返回體
                ResponseBody body = response.body();
            }
        });

以上就是發(fā)送一個(gè)異步的Get請(qǐng)求的主要步驟魔种。首先我們要?jiǎng)?chuàng)建一個(gè)OkHttpClickRequest.Builder()對(duì)象务嫡,再通過url()方法設(shè)置了網(wǎng)絡(luò)地址來指定訪問的目標(biāo)心铃,不僅如此 Request.Builder() 是支持鏈?zhǔn)骄幊痰模ǚ祷伢w是本體)在這里可以設(shè)置這些方法哦:

Request.Builder()鏈?zhǔn)骄幊倘タ郏诖瞬蛔鎏接?/div>

接下來我們就要將OkHttpClick的對(duì)象與Request的對(duì)象建立起來聯(lián)系愉棱,使用okHttpClicknewCall()方法得到一個(gè)Call對(duì)象奔滑,這個(gè)Call對(duì)象的作用就是相當(dāng)于將請(qǐng)求封裝成了一個(gè)任務(wù)朋其,既然是任務(wù)梅猿,自然就會(huì)有execute()和cancel()等方法袱蚓。

最后喇潘,我們希望以異步的方式去執(zhí)行請(qǐng)求颖低,所以我們調(diào)用的是call.enqueue枫甲,將call加入調(diào)度隊(duì)列想幻,然后等待任務(wù)執(zhí)行完成脏毯,我們?cè)贑allback中即可得到結(jié)果食店。但要注意的是,call的回調(diào)是子線程吉嫩,所以是不能直接操作界面的嗅定。使用時(shí)需要自行處理忙迁。當(dāng)請(qǐng)求成功時(shí)就會(huì)回調(diào)onResponse()方法碎乃,我們可以看到返回的結(jié)果是 Response對(duì)象,在此我們比較關(guān)注的是請(qǐng)求中的返回體bodyResponseBody類型)恰梢,大多數(shù)的情況下我們希望獲得字符串從而進(jìn)行json解析獲得數(shù)據(jù)删豺,所以可以通過body.string()的方式獲得字符串呀页。

ResponseBody 的 API

查看ResponseBody的API文檔可以看到,body還可以獲取byte[]丸氛、Reader缓窜、InputStream禾锤,其中最驚奇一點(diǎn)就是可以返回InputStream恩掷,這至少說明了OkHttp是可以支持大文件的下載的黄娘,這樣一來我們就可以輕松的使用InputStream進(jìn)行I/O方式的文件寫入啦1普5ǔā竿秆!幽钢。

讓我們實(shí)現(xiàn)一下吧:

        //step 1: 不變的第一步創(chuàng)建 OkHttpClick
        OkHttpClient okHttpClient = new OkHttpClient();

        //step 2: 創(chuàng)建Requset
        Request request = new Request.Builder()
                .url("http://www.ssyer.com/uploads/org_2017010593503_775.jpg")
                .build();
        
        //step 3:建立聯(lián)系匪燕,創(chuàng)建Call
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                try {
                    File file = new File(Environment.getExternalStorageDirectory() + "大獅子.jpg");
                    fileOutputStream = new FileOutputStream(file);
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Log.d("downloadAsynFile", "文件下載成功");
            }
        });

3.1.1 同步的Get

當(dāng)然Get也支持阻塞方式的同步請(qǐng)求,不過在開發(fā)中這種方法很少被使用书闸。上面我們也說了Call有一個(gè)execute()方法嫌术,你也可以直接調(diào)用call.execute()返回一個(gè)Response度气。然后利用isSuccessful()判讀是否成功,進(jìn)行相應(yīng)的結(jié)果解析磷籍。

3.2 異步的Http Post

在看過了Get請(qǐng)求方式弛矛,相信你對(duì)于請(qǐng)求的用法也用基本的掌握了汪诉,Post的使用使用方法和Get雖然存在些許差異,但是本質(zhì)是不變的拟烫。那么下面就讓我們以攜帶鍵值對(duì)的Post為例硕淑,先熟悉一下Post的使用方法吧置媳。

3.2.1 Post 上傳鍵值對(duì)

        //step 1: 同樣的需要?jiǎng)?chuàng)建一個(gè)OkHttpClick對(duì)象
        OkHttpClient okHttpClient = new OkHttpClient();

        //step 2: 創(chuàng)建  FormBody.Builder
        FormBody formBody = new FormBody.Builder()
                .add("name", "dsd")
                .build();

        //step 3: 創(chuàng)建請(qǐng)求
        Request request = new Request.Builder().url("http://www.baidu.com")
                .post(formBody)
                .build();

        //step 4: 建立聯(lián)系 創(chuàng)建Call對(duì)象
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // TODO: 17-1-4  請(qǐng)求失敗
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // TODO: 17-1-4 請(qǐng)求成功
            }
        });

是不是和Get很相似啊。大家都清楚公条,在使用Post的時(shí)候拇囊,參數(shù)是包含在請(qǐng)求體中的。所以我們通過FormBody靶橱,添加多個(gè)String鍵值對(duì)寥袭,然后為Request添加post(formBody)完成我們Request的構(gòu)造。之后的步驟就和Get的步驟一樣了关霸,是不是很簡(jiǎn)單按啤!

3.2.2 Post異步上傳文件

直接上代碼

       // step 1: 創(chuàng)建 OkHttpClient 對(duì)象
        OkHttpClient okHttpClient = new OkHttpClient();

        //step 2:創(chuàng)建 RequestBody 以及所需的參數(shù)
        //2.1 獲取文件
        File file = new File(Environment.getExternalStorageDirectory() + "test.txt");
        //2.2 創(chuàng)建 MediaType 設(shè)置上傳文件類型
        MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");
        //2.3 獲取請(qǐng)求體
        RequestBody requestBody = RequestBody.create(MEDIATYPE, file);

        //step 3:創(chuàng)建請(qǐng)求
        Request request = new Request.Builder().url("http://www.baidu.com")
                .post(requestBody)
                .build();

        //step 4 建立聯(lián)系
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // TODO: 17-1-4  請(qǐng)求失敗
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // TODO: 17-1-4 請(qǐng)求成功
            }
        });

當(dāng)然這里需要添加權(quán)限滴队寇,你是不是忘記了呢识埋。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

第一步與之前都相同相恃,但是從第二步開始就用了一定的差異了。在step2 中我們需要通過MediaType.parse("text/plain; charset=utf-8")為上傳文件設(shè)置一定類型(MIME)在這里我們上傳的純文本文件所以選擇"text/plain類型,而編碼格式為utf-8。下面為大家列出常見的文件類型,方便使用。

參數(shù) 說明
text/html HTML格式
text/plain 純文本格式
text/xml XML格式
image/gif gif圖片格式
image/jpeg jpg圖片格式
image/png png圖片格式
application/xhtml+xml XHTML格式
application/xml XML數(shù)據(jù)格式
application/atom+xml Atom XML聚合格式
application/json JSON數(shù)據(jù)格式
application/pdf pdf格式
application/msword Word文檔格式
application/octet-stream 二進(jìn)制流數(shù)據(jù)

其實(shí)MIME文件類型特批多坚俗,有興趣的朋友可以可參見w3school上的MIME 參考手冊(cè)

上傳類型

在創(chuàng)建RequestBody的時(shí)候可以看到破停,我們不僅僅可以上傳File文件黑界,還可以上傳StringByteStringbyte數(shù)組等類型,其中上傳byte數(shù)據(jù)時(shí)可以選擇三個(gè)參數(shù)的creta方法浦辨,需要指定偏移量和需要寫入的byte長(zhǎng)度,哈哈這不是說明可以直接進(jìn)行多線程、斷點(diǎn)上傳嗎艰躺!通過這些類型页响,我們可以上傳Json串涩哟,圖片等內(nèi)容真是方便又好用啊锻弓。

總結(jié)

經(jīng)過上面的介紹我相信大家對(duì)OkHttp簡(jiǎn)單使用有了一定的了解杂拨,OkHttp3使用起來是不是很簡(jiǎn)單呢炸渡,但是每一次請(qǐng)求的步驟都有著大量重復(fù)的地方,這要是在實(shí)際開發(fā)中藕夫,還不把人累著啊,本著節(jié)約開(tou)發(fā)周(lan)期的目的,咳咳沽瘦,后面的文章會(huì)進(jìn)一步的帶領(lǐng)大家學(xué)習(xí)OkHttp3的高級(jí)用法和OkHttp工具類的封裝哦并村,敬請(qǐng)期待。

參考:

  1. https://github.com/square/okhttp
  2. Android OkHttp完全解析 是時(shí)候來了解OkHttp了
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俄讹,一起剝皮案震驚了整個(gè)濱河市漱牵,隨后出現(xiàn)的幾起案子儒溉,更是在濱河造成了極大的恐慌蒲障,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仰迁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肯污,警方通過查閱死者的電腦和手機(jī)貌亭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蕊温,你說我怎么就攤上這事±龋” “怎么了皇忿?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵坦仍,是天一觀的道長(zhǎng)鳍烁。 經(jīng)常有香客問我,道長(zhǎng)繁扎,這世上最難降的妖魔是什么幔荒? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮梳玫,結(jié)果婚禮上爹梁,老公的妹妹穿的比我還像新娘。我一直安慰自己提澎,他們只是感情好姚垃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盼忌,像睡著了一般积糯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谦纱,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天看成,我揣著相機(jī)與錄音,去河邊找鬼跨嘉。 笑死川慌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梦重,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窜觉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼总珠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤椰于,失蹤者是張志新(化名)和其女友劉穎邪意,沒想到半個(gè)月后骨望,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粪牲,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年赢织,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亮靴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡于置,死狀恐怖茧吊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情八毯,我是刑警寧澤搓侄,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站话速,受9級(jí)特大地震影響讶踪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泊交,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一乳讥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧廓俭,春花似錦云石、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雹熬,卻和暖如春错维,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背橄唬。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留参歹,地道東北人仰楚。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親僧界。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侨嘀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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