1. 程式人生 > >Android網路請求:OkHttp實戰

Android網路請求:OkHttp實戰

android網路請求是個耗時的操作,一定要在子執行緒中執行,新增網路許可權,目前有很多流行的網路框架。比如okhttp,volley,xutils等等。今天主要介紹okhttp的使用,後續分享給多,比如socket網路請求,檔案上傳下載。

一,HTTP協議的主要特點

HTTP協議的主要特點可概括如下:
1.支援客戶/伺服器模式。
2.簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。
3.靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type加以標記。
4.無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。
詳見原文:

HTTP協議詳解(真的很經典)

二,OKHttp介紹

An HTTP & HTTP/2 client for Android and Java applications. For more information see the website and the wiki.前往OkHttp官網
使用okhttp很簡單,它的請求/響應 API設計,運用了流利的builder,確保方式多樣而又固定,支援非同步請求和回撥。它支援android 2.3或以上,jdk版本要求不低於1.7。

okhttp的主要特點:

  1. HTTP/2支援共享一個socket,傳送多個請求給相同的主機。
  2. 連線池減少了請求的潛在因素。
  3. 明顯的GZIP壓縮下載大小。
  4. 響應快取避免網路重複請求。

確保所有的網路請求只有一個OkHttpClient例項,可以用單例模式。也可以如下:

  public static OkHttpClient okHttpClient = new OkHttpClient();

okhttp傳送請求,封裝的方法,必須在子執行緒執行。另外回撥方法是在子執行緒中,要更新UI必須在主執行緒,自己處理。下面的方法中的OkHttpClient例項統一用上面生成的。

三,okhttp傳送get請求

演示基本的用法,不懂的地方可以github下載原始碼研究。

//OKHTTP GET
public static String get(String url){ Request request = new Request.Builder().url(url).build(); Response response = null; try { response = new OkHttpClient().newCall(request).execute(); if (response.isSuccessful()) { return response.body().string(); } else { throw new IOException("Unexpected code " + response); } } catch (IOException e) { e.printStackTrace(); } return ""; }

四,OKHttp構建RequestBody

傳送post的請求,比較普遍。無論有一個引數,多個引數,或者檔案上傳,都可以構建特定的RequestBody傳送請求。

1.傳送一個鍵值對。

RequestBody requestBody = RequestBody.create(MediaType.parse("UTF-8"),"param=value");

2.傳送多個引數,構建表單一樣的請求引數。

RequestBody requestBody = new FormBody.Builder()
                .add("param1", "value1")
                .add("param12", "value2")
                .build();

3. post json字串

MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, json);

4. 檔案上傳

MediaType,檔案型別標示,通常”application/octet-stream”就可以,比如jpg圖片,可以MediaType.parse(“image/jpg”)。表單引數根據專案需要自行調整。

final MediaType mediaType = MediaType.parse("application/octet-stream");
            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MediaType.parse("multipart/form-data"));
            builder.addFormDataPart("description", description);
            builder.addFormDataPart("file", fileName, RequestBody.create(mediaType, uploadFile));
   //構建請求體
  RequestBody requestBody = builder.build();

五,傳送的post請求的方法

 //使用Request的post方法來提交請求體RequestBody
    public static String post(String url, RequestBody requestBody) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

六,Headers相關。

先看官方對header和addHeader兩種方法的解釋:

   /**
     * Sets the header named {@code name} to {@code value}. If this request already has any headers
     * with that name, they are all replaced.
     */
    public Builder header(String name, String value) {
      headers.set(name, value);
      return this;
    }

    /**
     * Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued
     * headers like "Cookie".
     *
     * <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding},
     * OkHttp may replace {@code value} with a header derived from the request body.
     */
    public Builder addHeader(String name, String value) {
      headers.add(name, value);
      return this;
    }

意思就是說,header是給已有的請求頭設定一個值,
addHeader是新增新的請求頭,value的值可以有多個(以英文”,”分開)。例如:

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {
  Request request = new Request.Builder()
      .url("https://api.github.com/repos/square/okhttp/issues")
      .header("User-Agent", "OkHttp Headers.java")
      .addHeader("Accept", "application/json; q=0.5")
      .addHeader("Accept", "application/vnd.github.v3+json")
      .build();

  Response response = client.newCall(request).execute();
  if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    LogUtils.debug("Server:"+response.header("Server"));
    LogUtils.debug("Date: " + response.header("Date"));
    LogUtils.debug("Vary: " + response.headers("Vary"));
}

返回結果:

Server: GitHub.com
Sat, 30 Apr 2016 01:24:48 GMT
Vary: [Accept, Accept-Encoding]

七,總結

okhttp是目前比較流行的網路框架,開源專案,本文介紹了本人一些常用的用法,不到之處望留言指出。對比了一些網路框架,還是挺讚的。
有時間再研究研究原始碼,未完待續,歡迎交流,杜乾,Dusan,Q 291902259。