okhttp

OkHttp 封裝了請求和緩存和緩存html

OkHttp是一個相對成熟的解決方案,聽說Android4.4的源碼中能夠看到HttpURLConnection已經替換成OkHttp實現了。因此咱們更有理由相信OkHttp的強大。java

OkHttp 處理了不少網絡疑難雜症:會從不少經常使用的鏈接問題中自動恢復。若是您的服務器配置了多個IP地址,當第一個IP鏈接失敗的時候,OkHttp會自動嘗試下一個IP。OkHttp還處理了代理服務器問題和SSL握手失敗問題。android

使用 OkHttp 無需重寫您程序中的網絡代碼。OkHttp實現了幾乎和HttpURLConnection同樣的API。若是你用了 Apache HttpClient,則OkHttp也提供了一個對應的okhttp-apache 模塊。git

OkHttp 和 fresco  retrofit 等第三方庫能很好的銜接。github

Okhttp做爲HTTP引擎,retrofit做爲restful業務架構實現;目前retrofit的restful風格規範是趨勢。apache

OkHttp是一個高效的Http客戶端數組

  1. 支持HTTP2/SPDY黑科技
  2. socket自動選擇最好路線,並支持自動重連
  3. 擁有自動維護的socket鏈接池,減小握手次數
  4. 擁有隊列線程池,輕鬆寫併發
  5. 擁有Interceptors輕鬆處理請求與響應(好比透明GZIP壓縮,LOGGING)
  6. 基於Headers的緩存策略

注:什麼是SPDY緩存

SPDY(讀做「SPeeDY」)是 Google開發的基於 TCP的傳輸層協議,用以最小化網絡延遲,提高網絡速度,優化用戶的網絡使用體驗。SPDY並非一種用於替代HTTP的協議,而是對 HTTP協議的加強。新協議的功能包括數據流的多路複用、請求優先級以及HTTP報頭壓縮。谷歌表示,引入SPDY協議後,在實驗室測試中頁面加載速度比原先快64%。中文名:spdy協議,目前SPDY已經被Http/2代替,google已經宣佈要移除SPDY;

主要對象

  • Connections: 對JDK中的socket進行了引用計數封裝,用來控制socket鏈接
  • Streams: 維護HTTP的流,用來對Requset/Response進行IO操做
  • Calls: HTTP請求任務封裝
  • StreamAllocation: 用來控制Connections/Streams的資源分配與釋放

工做流程的概述服務器

當咱們用OkHttpClient.newCall(request)進行execute/enenqueue時,實際是將請求Call放到了Dispatcher中,okhttp使用Dispatcher進行線程分發,它有兩種方法,一個是普通的同步單線程;另外一種是使用了隊列進行併發任務的分發(Dispatch)與回調,咱們下面主要分析第二種,也就是隊列這種狀況,這也是okhttp可以競爭過其它庫的核心功能之一; restful

Socket管理(StreamAllocation)

通過上一步的分配,咱們如今須要進行鏈接了。咱們目前有封裝好的Request,而進行HTTP鏈接須要進行Socket握手,Socket握手的前提是根據域名或代理肯定Socket的ip與端口。這個環節主要講了http的握手過程與鏈接池的管理,分析的對象主要是StreamAllocation。

 

Githug:  https://github.com/square/okhttp

wiki:https://github.com/square/okhttp/wiki

中文翻譯wiki

OKHttp源碼解析

配置方法:

注意:okhttp內部依賴okio,別忘了同時導入okio

(1)Android Studio:

1 compile 'com.squareup.okhttp:okhttp:2.4.0'

導入okio:

1 compile 'com.squareup.okio:okio:1.5.0'

(2)Eclipse:

能夠下載最新的jar okhttp he latest JAR ,添加依賴就能夠用了

最新的jar地址:okio the latest JAR

 

使用:

1 //建立okHttpClient對象
2 OkHttpClient mOkHttpClient = new OkHttpClient();
3 // 建立Request.Builder  post請求方式
4 Request.Builder builder = new Request.Builder().post()
5                 .url("https://github.com/hongyangAndroid");
6 //建立一個Request
7 final Request request = builder.build();
8 //經過請求request,構造出call
9 Call call = mOkHttpClient.newCall(request); 

(1)Request.Builder

經過Request.Builder設置更多的參數好比:

(1) 添加請求頭header:

若是它自己存在值,在添加新的value以前,他們會被移除。使用addHeader(name, value)來添加頭部不須要移除當前存在的headers。

1 builder.addHeader("SYSVERSION",  "1.01");

當寫請求頭,構造時用header(name, value)來爲惟一出現的name設置value。

1 Request.Builder builder = new Request.Builder().post()
2                  .url("https://github.com/hongyangAndroid")
3                  .header("Cookie", "OkHttpUser");

(2)添加method

請求攜帶參數:

post方式:

發佈表單參數

 1 String url = url;
 2 // 建立builder
 3 FormBody.Builder builder = new FormBody.Builder();
 4 requestBody.add("user", "charles");
 5 requestBody.add("age", "12");
 6 // 建立RequestBody
 7 RequestBody requestBody = builder.build();
 8 
 9 Request request = new Request.Builder().post(requestBody ).url(url).build();
10 Response response = mOKHttpClient.newCall(request).execute();

發佈multipart請求

MultipartBody.Builder能夠構建與HTML文件上傳表單兼容的複雜請求主體。例如文件上傳

視頻類:MediaType.parse("application/octet-stream")

 1 File file = new File(Environment.getExternalStorageDirectory(), "about.jpg");
 2 
 3 RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
 4 
 5 RequestBody requestBody = new MultipartBuilder()
 6      .type(MultipartBuilder.FORM)
 7      .addPart(Headers.of(
 8           "Content-Disposition", 
 9               "form-data; name=\"username\""), 
10           RequestBody.create(null, "charles"))
11      .addPart(Headers.of(
12          "Content-Disposition", 
13          "form-data; name=\"imagefile\"; 
14          filename=\"aboutApp.jpg\""), fileBody)
15      .build();
16 
17 Request request = new Request.Builder()
18     .url("http://.../fileUpload")
19     .post(requestBody)
20     .build();
21 
22 Reponse reponse = mOkHttpClient.newCall(request).execute();

get方式:

1 String url = url + "?" + "user=charles" + "&age=12" 
2 Request request = new Request.Builder().get().url(url).build();
3 Response response = mOKHttpClient.newCall(request).execute();

執行call:

(1)異步

調用call.enqueue,將call加入調度隊列,等待任務執行完成,在Callback中便可獲得結果。

 1 // 異步執行call
 2 call.enqueue(new Callback()
 3         {
 4             @Override
 5             public void onFailure(Request request, IOException e)
 6             {
 7             }
 8 
 9             @Override
10             public void onResponse(final Response response) throws IOException
11             {
12                  String htmlStr =  response.body().string();// 當前線程不是ui線程 13             }
14         });  

(2)同步,阻塞方式:

1 Response response = call.execute();

Response:

(1)返回字符串,經過response.body().string()獲取;

(2)返回二進制字節數組,經過response.body().bytes()獲取

(3)返回inputStream,經過response.body().byteStream()獲取 (支持大文件下載);

相關文章
相關標籤/搜索