一、前言
自從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è)OkHttpClick
和Request.Builder()
對(duì)象务嫡,再通過url()
方法設(shè)置了網(wǎng)絡(luò)地址來指定訪問的目標(biāo)心铃,不僅如此 Request.Builder()
是支持鏈?zhǔn)骄幊痰模ǚ祷伢w是本體)在這里可以設(shè)置這些方法哦:
接下來我們就要將OkHttpClick
的對(duì)象與Request
的對(duì)象建立起來聯(lián)系愉棱,使用okHttpClick
的newCall()
方法得到一個(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)求中的返回體body
(ResponseBody
類型)恰梢,大多數(shù)的情況下我們希望獲得字符串從而進(jìn)行json解析獲得數(shù)據(jù)删豺,所以可以通過body.string()
的方式獲得字符串呀页。
查看
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文件黑界,還可以上傳String
,ByteString
,byte
數(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)期待。
參考:
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蕊温,你說我怎么就攤上這事±龋” “怎么了皇忿?”我有些...
- 文/不壞的土叔 我叫張陵坦仍,是天一觀的道長(zhǎng)鳍烁。 經(jīng)常有香客問我,道長(zhǎng)繁扎,這世上最難降的妖魔是什么幔荒? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮梳玫,結(jié)果婚禮上爹梁,老公的妹妹穿的比我還像新娘。我一直安慰自己提澎,他們只是感情好姚垃,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盼忌,像睡著了一般积糯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谦纱,一...
- 文/蒼蘭香墨 我猛地睜開眼窜觉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼总珠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬榮一對(duì)情侶失蹤椰于,失蹤者是張志新(化名)和其女友劉穎邪意,沒想到半個(gè)月后骨望,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粪牲,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年赢织,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亮靴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布,位于F島的核電站话速,受9級(jí)特大地震影響讶踪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泊交,卻給世界環(huán)境...
- 文/蒙蒙 一乳讥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧廓俭,春花似錦云石、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雹熬,卻和暖如春错维,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背橄唬。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親僧界。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侨嘀,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)捂襟,斷路器咬腕,智...
- Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
- 參考Android網(wǎng)絡(luò)請(qǐng)求心路歷程Android Http接地氣網(wǎng)絡(luò)請(qǐng)求(HttpURLConnection) 一...
- 這篇文章主要總結(jié)Android著名網(wǎng)絡(luò)框架-okhttp的基礎(chǔ)使用。 okhttp是什么 okhttp是Andro...
- 這兩天孩子剛開始有點(diǎn)小咳嗽,我馬上就給他吃了頭孢克肟顆粒和小兒化痰止咳顆粒宠漩,但是到了6月29日晚上突然咳嗽加重举反,而...