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 官方文檔

要知道學習一門新技術,最好的資料永遠是官方文檔:

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 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工具類的封裝哦,敬請期待。

參考:

  1. https://github.com/square/okhttp
  2. Android OkHttp完全解析 是時候來了解OkHttp了

 

來自:http://www.jianshu.com/p/7d88613c0b0f

 

 本文由用戶 TracyXZYV 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!