OkHttp3 最有營養的初級教程,快來圍觀吧
一、前言
自從Android4.4開始,google已經開始將源碼中的HttpURLConnection替換為OkHttp,而在Android6.0之后的SDK中google更是移除了對于HttpClient的支持,而市面上流行的Retrofit同樣是使用OkHttp進行再次封裝而來的。由此看見學習OkHttp的重要性。
本篇文章是以當前最新的版本 3.5.0為例(2.0及以上版本版本與3.0以上版本存在較大差異,本文不做深入討論,請自行百度),使用Android Stuido作為開發環境,帶領大家簡單的熟悉OKHttp的使用情況。作為《Android網絡編程》系類文章之一,后面的文章會圍繞OKHttp3做逐漸深入的探討。這篇文章我們要達到的 目的就是:不深究,簡單明了,可以直接粘貼復制。
二、使用前的準備
2.1 官方文檔
要知道學習一門新技術,最好的資料永遠是官方文檔:
2.2 Android Studio 配置gradle環境:
compile 'com.squareup.okhttp3:okhttp:3.5.0'
compile 'com.squareup.okio:okio:1.11.0'
2.3 添加網絡權限
不要忘記添加權限啊,這也是常常被開發忽略的地方
<uses-permission android:name="android.permission.INTERNET"/>
三、使用教程
3.1 Http Get
3.1.1 異步的Get
在Http請求中最常見的就是get方法了,在大多數的使用場景中,我們使用的都是異步的Get請求,下面我們就是用OkHttp的異步Get去請求一下百度的首頁。
// step 1: 創建 OkHttpClient 對象
OkHttpClient okHttpClient = new OkHttpClient();
// step 2: 創建一個請求,不指定請求方法時默認是GET。
Request.Builder requestBuilder = new Request.Builder().url("http://www.baidu.com");
//可以省略,默認是GET請求
requestBuilder.method("GET",null);
// step 3:創建 Call 對象
Call call = okHttpClient.newCall(requestBuilder.build());
//step 4: 開始異步請求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// TODO: 17-1-4 請求失敗
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// TODO: 17-1-4 請求成功
//獲得返回體
ResponseBody body = response.body();
}
});
以上就是發送一個異步的Get請求的主要步驟。首先我們要創建一個 OkHttpClick 和 Request.Builder() 對象,再通過 url() 方法設置了網絡地址來指定訪問的目標,不僅如此 Request.Builder() 是支持鏈式編程的(返回體是本體)在這里可以設置這些方法哦:
Request.Builder()鏈式編程,在此不做探討
接下來我們就要將 OkHttpClick 的對象與 Request 的對象建立起來聯系,使用 okHttpClick 的 newCall() 方法得到一個 Call 對象,這個Call對象的作用就是相當于將請求封裝成了一個任務,既然是任務,自然就會有execute()和cancel()等方法。
最后,我們希望以異步的方式去執行請求,所以我們調用的是call.enqueue,將call加入調度隊列,然后等待任務執行完成,我們在Callback中即可得到結果。 但要注意的是,call的回調是子線程,所以是不能直接操作界面的。使用時需要自行處理 。當請求成功時就會回調 onResponse() 方法,我們可以看到返回的結果是 Response 對象,在此我們比較關注的是請求中的返回體 body ( ResponseBody 類型),大多數的情況下我們希望獲得字符串從而進行json解析獲得數據,所以可以通過 body.string() 的方式獲得字符串。
ResponseBody 的 API
查看 ResponseBody 的API文檔可以看到, body 還可以獲取byte[]、Reader、InputStream,其中最驚奇一點就是可以返回InputStream,這至少說明了OkHttp是可以支持大文件的下載的,這樣一來我們就可以輕松的使用InputStream進行I/O方式的文件寫入啦!!!。
讓我們實現一下吧:
//step 1: 不變的第一步創建 OkHttpClick
OkHttpClient okHttpClient = new OkHttpClient();
//step 2: 創建Requset
Request request = new Request.Builder()
.url("http://www.ssyer.com/uploads/org_2017010593503_775.jpg")
.build();
//step 3:建立聯系,創建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
當然 Get 也支持阻塞方式的同步請求,不過在開發中這種方法很少被使用。上面我們也說了Call有一個 execute() 方法,你也可以直接調用 call.execute() 返回一個 Response 。然后利用 isSuccessful() 判讀是否成功,進行相應的結果解析。
3.2 異步的Http Post
在看過了 Get 請求方式,相信你對于請求的用法也用基本的掌握了, Post 的使用使用方法和 Get 雖然存在些許差異,但是本質是不變的。那么下面就讓我們以攜帶鍵值對的 Post 為例,先熟悉一下 Post 的使用方法吧。
3.2.1 Post 上傳鍵值對
//step 1: 同樣的需要創建一個OkHttpClick對象
OkHttpClient okHttpClient = new OkHttpClient();
//step 2: 創建 FormBody.Builder
FormBody formBody = new FormBody.Builder()
.add("name", "dsd")
.build();
//step 3: 創建請求
Request request = new Request.Builder().url("http://www.baidu.com")
.post(formBody)
.build();
//step 4: 建立聯系 創建Call對象
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// TODO: 17-1-4 請求失敗
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// TODO: 17-1-4 請求成功
}
});
是不是和 Get 很相似啊。大家都清楚,在使用 Post 的時候,參數是包含在請求體中的。所以我們通過 FormBody ,添加多個String鍵值對,然后為 Request 添加 post(formBody) 完成我們 Request 的構造。之后的步驟就和Get的步驟一樣了,是不是很簡單啊!
3.2.2 Post異步上傳文件
直接上代碼
// step 1: 創建 OkHttpClient 對象
OkHttpClient okHttpClient = new OkHttpClient();
//step 2:創建 RequestBody 以及所需的參數
//2.1 獲取文件
File file = new File(Environment.getExternalStorageDirectory() + "test.txt");
//2.2 創建 MediaType 設置上傳文件類型
MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");
//2.3 獲取請求體
RequestBody requestBody = RequestBody.create(MEDIATYPE, file);
//step 3:創建請求
Request request = new Request.Builder().url("http://www.baidu.com")
.post(requestBody)
.build();
//step 4 建立聯系
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// TODO: 17-1-4 請求失敗
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// TODO: 17-1-4 請求成功
}
});
當然這里需要添加權限滴,你是不是忘記了呢。
<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") 為上傳文件設置一定類型(MIME)在這里我們上傳的純文本文件所以選擇 "text/plain 類型,而編碼格式為 utf-8 。下面為大家列出常見的文件類型,方便使用。
參數 | 說明 |
---|---|
text/html | HTML格式 |
text/plain | 純文本格式 |
text/xml | XML格式 |
image/gif | gif圖片格式 |
image/jpeg | jpg圖片格式 |
image/png | png圖片格式 |
application/xhtml+xml | XHTML格式 |
application/xml | XML數據格式 |
application/atom+xml | Atom XML聚合格式 |
application/json | JSON數據格式 |
application/pdf | pdf格式 |
application/msword | Word文檔格式 |
application/octet-stream | 二進制流數據 |
上傳類型
在創建 RequestBody 的時候可以看到,我們不僅僅可以上傳File文件,還可以上傳 String , ByteString , byte 數組等類型,其中上傳byte數據時可以選擇三個參數的creta方法,需要指定偏移量和需要寫入的byte長度,哈哈這不是說明可以直接 進行多線程、斷點上傳 嗎!通過這些類型,我們可以上傳Json串,圖片等內容真是方便又好用啊。
總結
經過上面的介紹我相信大家對OkHttp簡單使用有了一定的了解,OkHttp3使用起來是不是很簡單呢,但是每一次請求的步驟都有著大量重復的地方,這要是在實際開發中,還不把人累著啊,本著節約開(tou)發周(lan)期的目的,咳咳,后面的文章會進一步的帶領大家學習OkHttp3的高級用法和OkHttp工具類的封裝哦,敬請期待。
參考:
來自:http://www.jianshu.com/p/7d88613c0b0f