OKHTTP 簡單分析

来源:http://www.cnblogs.com/sphere/archive/2017/11/09/7810374.html
-Advertisement-
Play Games

內部使用了OKIO庫, 此庫中Source表示輸入流(相當於InputStream),Sink表示輸出流(相當於OutputStream) 特點: ·既支持同步請求,也支持非同步請求,同步請求會阻塞當前線程,非同步請求不阻塞當前線程,非同步執行完成後回掉相應的方法 ·支持HTTP/2協議,通過HTTP/2 ...


  

內部使用了OKIO庫, 此庫中Source表示輸入流(相當於InputStream),Sink表示輸出流(相當於OutputStream)

    特點:

    ·既支持同步請求,也支持非同步請求,同步請求會阻塞當前線程,非同步請求不阻塞當前線程,非同步執行完成後回掉相應的方法

    ·支持HTTP/2協議,通過HTTP/2 可以讓客戶端中到伺服器的所有請求共用同一個Socket連接

    ·非HTTP/2 請求時, OKHTTP內部會維護一個線程池,通過線程池可以對HTTP/1.x的連接進行復用,減少延遲

    ·透明的Gzip處理降低了通信數據的大小

    ·請求的數據可以進行緩存

 

重要的類:

   ·Request 請求類,OKHTTP中大量使用了Builder構建器模式,Request也不例外,其內部有靜態內部類Builder, 封裝了請求url,請求方法method,請求頭headers, 請求體RequestBody,請求標記tag

    ·Headers類, 被封裝在Request或Response中,其內部使用一維數組String[] namesAndValues表示header的key value信息,可以看到除了導入包中的Util、HttpDate類之外,跟OKHTTP的關聯並不大,可以將此類copy出來單獨分析。在Builder內部類中有一個ArrayList<String> namesAndValues

,當我們添加header鍵值對時,調用add方法,最終調用addLenient()方法將name,value的值依次添加到列表中,列表內部按照name,value,name2,value2,name3,value3...的順序排列,在build()方法中調用toArray方法再轉換為String數組,內部元素的順序不變,這樣在用get方法查找的時候

private static String get(String[] namesAndValues, String name) {
    for (int i = namesAndValues.length - 2; i >= 0; i -= 2) {
      if (name.equalsIgnoreCase(namesAndValues[i])) {
        return namesAndValues[i + 1];
      }
    }
    return null;
  }

  

可以先查找對應的name,得到name對應的索引後,那麼value是緊隨name其後的,自然可以得到value的值。且在查找的時候i的值可以每隔2做一次處理。這樣有些巧妙的設計,避免使用Map去存儲鍵值對,一定程度上提高了效率。 由於在調用get方法時是倒序查找,故添加相同的欄位時,取最後一個的值。如果使用set(String name, String value) 則會移除舊的name和value。需要註意的是有時候響應頭含有多個重覆name的header, 比如有個多 Set-Cookie,這時候可以調用 values(String name)便可以獲得多個值。

    ·ResponseBody 內部使用了OKIO, 可以得到位元組數組 bytes(), 字元串結果string(),或者是輸入流 byteStream, 特別需要註意的是bytes() string() 方法的註釋,這兩個方法會將響應實體內容全部載入到記憶體中,所以如果響應實體比較大的話,應該考慮使用流的形式讀取。其中charStream()使用響應頭Content-Type指定的字元集來解析響應體。預設是UTF-8

 

Call

    同步方法execute() 會阻塞當前線程直到有響應。

    非同步方法 enqueue(Callback responseCallback)

 

OKHttpClient

    內部也使用Builder構建器模式,可以配置超時時間,緩存,代理,攔截器等

 

Force a Network Response

    在某些情形下,例如點擊了刷新按鈕之後,有必要跳過緩存,直接向伺服器獲取資源,為了獲得刷新後的資源可以 添加 Connection.addRequestProperty(“Cache-Control”, “no-cache”), 或者可以直接使用 connection.addRequestProperty(“Cache-Control”, “max-age=0”);

Force a Cache Response

    Connection.addRequestProperty(“Cache-Control”, “only-if-cached”);

 

請求的流程:

    ·非同步請求

         創建Request ,執行client.newCall(request).enqueue(Callback)方法,跟蹤newCall方法,方法內部new了一個RealCall,RealCall實現了Call介面,查看RealCall的enqueue方法,最終調用client.dispatcher().enqueue(new AsyncCall(responseCallback);其中Dispatcher內部封裝了線程池(可以看到預設的線程池也是沒有核心線程, 和Android-Async-http的預設線程池一致),查看Dispatcher的enqueue方法可以看到如果正在請求的call數量小於最大請求數,則將call添加到runningAsyncCalls中,並提交call到線程池中(AsyncCall實現了Runnable的介面), 查看AsyncCall的構造方法,可以看到傳入響應的回調,AsyncCall提交到線程池中後,run方法中會調用execute方法,

在AsyncCall的execute方法中通過getResponseWithInterceptorChain()方法得到Response,併進行響應的請求成功或失敗的回調,然後調用finished方法移除之前添加到Queue中的call。

    

上傳文件:

OkHttpClient httpClient = new OkHttpClient();

RequestBody requestBody = FormBody.create(MediaType.parse("image/jpeg"),
		new File(getExternalCacheDir()+ File.separator +"IMG_20171106_202814.jpg"));

MultipartBody multipartBody = new MultipartBody.Builder()
		.setType(MultipartBody.FORM)
		.addFormDataPart("uploadimg", "IMG_20171106_202814.jpg", requestBody)
		.build();

Request request = new Request.Builder().url("http://www.chuantu.biz/upload.php")
		.addHeader("Cache-Control", "max-age=0")
		.addHeader("Upgrade-Insecure-Requests", "1")
		.addHeader("Accept-Language","zh-CN,zh;q=0.8")
		.post(multipartBody).build();

Call call = httpClient.newCall(request);
call.enqueue(new Callback() {
	@Override
	public void onFailure(Call call, IOException e) {
	}

	@Override
	public void onResponse(Call call, Response response) throws IOException {

		Log.d("song", response.body().string());
	}
});

  

Fidddler抓包的截圖

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 個人博客記錄:2017-11-09 png 32位無損壓縮演算法形成的圖片,主要用於logo小圖標和一些點綴的小圖像。放大縮小不會失真,質量好 jpeg,jpg 壓縮比例較高(可達到100:1,即壓縮一百倍),放大縮小失真。適用於比較大的圖片,省流量 gif 動態圖,(你懂得),適用於動畫效果。 ...
  • 效果圖展示: 原理很簡單,主要運用transform這個樣式,通過斜切和旋轉達成 html: css: 怎樣,是不是很簡單 ...
  • 在Web前端頁面實現圓角效果,CSS3幫你輕鬆實現,一個人人皆知的屬性 圓角邊框的繪製是Web頁面和Web應用程式中經常用來美化頁面效果的手法之一。今天,小編為大家介紹CSS3提供的可以將矩形變為圓角矩形的一個屬性 技術等級:中級 | 適合有一定的CSS基礎的人士閱讀。 希望收藏了這篇文章的你同時也 ...
  • 前言 需要用到圖形繪製,沒有找到完整的圖形繪製實現,所以自己實現了一個 - - 一、實現的功能 1、基於oop思想構建,支持坐標點、線條(由坐標點組成,包含方向)、多邊形(由多個坐標點組成)、圓形(包含圓心坐標點和半徑)等實體 2、原生JavaScript實現,不依賴任何第三方js庫和插件 3、多圖 ...
  • 我們平時在同域中請求頁面什麼的時候不會有這種情況,這種情況大多發生在移動端的跨域請求中發生的。 解決方法就是在服務端中加一層過濾HTTP請求的類型,把OPTION等不用的類型過濾掉。就是當請求為非 HTTP中的 GET 和 POST的時候就不執行下麵的代碼,這樣就可以只執行一次請求了。 在ASP.N ...
  • vue.js 一個簡單快捷的JS框架 vue.js 一個簡單快捷的JS框架 vue.js擁有簡單小巧的核心,漸進式技術棧,代碼簡單易學。 雙向綁定 什麼是雙向綁定? 雙向綁定 什麼是雙向綁定? Vue框架 很核心的功能就是雙向的數據綁定 ,雙向是指 HTML標簽數據綁定到Vue對象,另外反方向的數據 ...
  • 在Activity 的啟動過程中,調用ActivityThread 的handleResumeActivity 方法時,先得到一個與Activity 關聯的PhoneWindow 對象,然後通過PhoneWindow 來獲取DecorView。 PhoneWindow.java DecorView ...
  • iOS UImage 與 RGB 裸數據的相互轉換 Touch the data of image in iOS Get data from a image 較簡單,根據已有的 image 的屬性,創建 CGBitmapContext, 這個 context 是帶有直接訪問的指針的。然後將 Imag ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...