標籤:最好 director gem comment 類型 網路 leo cep blank
一、前言
自從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 官方文檔
要知道學習一門新技術,最好的資料永遠是官方文檔:
OkHttp官方介紹
github源碼
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 Get3.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 |
二進位流資料 |
其實MIME檔案類型特批多,有興趣的朋友可以可參見w3school上的MIME 參考手冊。
上傳類型
在建立RequestBody的時候可以看到,我們不僅僅可以上傳File檔案,還可以上傳String,ByteString,byte數組等類型,其中上傳byte資料時可以選擇三個參數的creta方法,需要指定位移量和需要寫入的byte長度,哈哈這不是說明可以直接進行多線程、斷點上傳嗎!通過這些類型,我們可以上傳Json串,圖片等內容真是方便又好用啊。
總結
經過上面的介紹我相信大家對OkHttp簡單使用有了一定的瞭解,OkHttp3使用起來是不是很簡單呢,但是每一次請求的步驟都有著大量重複的地方,這要是在實際開發中,還不把人累著啊,本著節約開(tou)發周(lan)期的目的,咳咳,後面的文章會進一步的帶領大家學習OkHttp3的進階用法和OkHttp工具類的封裝哦,敬請期待。
參考:
- https://github.com/square/okhttp
- Android OkHttp完全解析 是時候來瞭解OkHttp了
(原文地址:http://www.jianshu.com/p/7d88613c0b0f)
[轉]OkHttp3 最有營養的初級教程