天天看點

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

Android Http網絡開發神兵利器

  • Android Http網絡開發神兵利器
  • Http協定
    • HTTP簡介
    • 主要特點
    • Request
    • Response
    • Code
    • Method
    • Header
  • 網絡請求庫
    • URLConnection
    • Apache HttpClient
    • Volley
    • OkHttp Retrofit
  • 工具
    • Charles
    • PostMan Paw
    • Chrome Dev Tools
    • curl
  • OkHttp相關
    • logging-interceptor
    • Stetho
    • chuck
  • 其他
    • RESTful
  • 總結
    • 心得
    • 工具對比
      • Charles Fiddler
      • OkHttp相關
    • 其他建議
  • 參考資料

本人在Android移動端開發已經有不少年的經驗,經曆頗多,感受頗深,特寫下此文記錄下在Android Http網絡開發中的各種工具使用,如果有其他想法和建議,歡迎前來交流 [email protected] 。 本人文筆較差,請不要見怪。

Android開發的時候,很多APP都是基于網絡請求的,大部分應用都是基于http的,少部分是基于Socket的,本文主要介紹Android Http開發的主要實踐和工具。

本文最先發表于Github,如有轉載,請注明轉載出處。

Http協定

說起Http網絡請求,那麼要介紹下Http協定,我在公司面試的時候也很喜歡問這個問題。很多做好了3-5年的工程師,竟然不知道Http協定,隻知道怎麼調用類庫,不知道原理。

作為一個有追求的程式員,Http協定還是需要了解的。知其然知其是以然,在了解Http協定的情況下,才能在實際開發中靈活運用和優化。

這裡有篇 文章 ,Http協定介紹的很詳細。

HTTP簡介

HTTP協定是Hyper Text Transfer Protocol(超文本傳輸協定)的縮寫,是用于從網際網路(WWW:World Wide Web )伺服器傳輸超文本到本地浏覽器的傳送協定。

HTTP是一個基于TCP/IP通信協定來傳遞資料(HTML 檔案, 圖檔檔案, 查詢結果等)。

HTTP是一個屬于應用層的面向對象的協定,由于其簡捷、快速的方式,适用于分布式超媒體資訊系統。它于1990年提出,經過幾年的使用與發展,得到不斷地完善和擴充。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的規範化工作正在進行之中,而且HTTP-NG(Next Generation of HTTP)的建議已經提出。

HTTP協定工作于用戶端-服務端架構為上。浏覽器作為HTTP用戶端通過URL向HTTP服務端即WEB伺服器發送所有請求。Web伺服器根據接收到的請求後,向用戶端發送響應資訊。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

主要特點

1、簡單快速:客戶向伺服器請求服務時,隻需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯系的類型不同。由于HTTP協定簡單,使得HTTP伺服器的程式規模小,因而通信速度很快。

2、靈活:HTTP允許傳輸任意類型的資料對象。正在傳輸的類型由Content-Type加以标記。

3.無連接配接:無連接配接的含義是限制每次連接配接隻處理一個請求。伺服器處理完客戶的請求,并收到客戶的應答後,即斷開連接配接。采用這種方式可以節省傳輸時間。

4.無狀态:HTTP協定是無狀态協定。無狀态是指協定對于事務處理沒有記憶能力。缺少狀态意味着如果後續處理需要前面的資訊,則它必須重傳,這樣可能導緻每次連接配接傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

5、支援B/S及C/S模式。

Request

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

上圖是一個Http請求消息結構,我們可以使用抓包工具抓取網絡請求,因為是Get請求,是以後面沒有請求資料

GET /f25980001b1b106000338.jpg HTTP/
Host    img.mukewang.com
User-Agent    Mozilla/ (Windows NT ; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Accept    image/webp,image/*,*/*;q=0.8
Referer    http://www.imooc.com/
Accept-Encoding    gzip, deflate, sdch
Accept-Language    zh-CN,zh;q=0.8
           

第一部分:請求行,用來說明請求類型,要通路的資源以及所使用的HTTP版本.

GET說明請求類型為GET,[/562f25980001b1b106000338.jpg]為要通路的資源,該行的最後一部分說明使用的是HTTP1.1版本。

第二部分:請求頭部,緊接着請求行(即第一行)之後的部分,用來說明伺服器要使用的附加資訊

從第二行起為請求頭部,HOST将指出請求的目的地.User-Agent,伺服器端和用戶端腳本都能通路它,它是浏覽器類型檢測邏輯的重要基礎.該資訊由你的浏覽器來定義,并且在每個請求中自動發送等等

第三部分:空行,請求頭部後面的空行是必須的

即使第四部分的請求資料為空,也必須有空行。

第四部分:請求資料也叫主體,可以添加任意的其他資料。

這個例子的請求資料為空。

下面這個例子是Post方式。

POST / HTTP1.
Host:www.wrox.com
User-Agent:Mozilla/ (compatible; MSIE ; Windows NT ; SV1; .NET CLR .; .NET CLR ..; .NET CLR .)
Content-Type:application/x-www-form-urlencoded
Content-Length:
Connection: Keep-Alive

name=Professional%Ajax&publisher=Wiley
           

第一部分:請求行,第一行明了是post請求,以及http1.1版本。

第二部分:請求頭部,第二行至第六行。

第三部分:空行,第七行的空行。

第四部分:請求資料,第八行。

Response

一般情況下,伺服器接收并處理用戶端發過來的請求後會傳回一個HTTP的響應消息。

HTTP響應也由四個部分組成,分别是:狀态行、消息報頭、空行和響應正文。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料
HTTP/1.1  OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
      <head></head>
      <body>
            <!--body goes here-->
      </body>
</html>
           

第一部分:狀态行,由HTTP協定版本号, 狀态碼, 狀态消息 三部分組成。

第一行為狀态行,(HTTP/1.1)表明HTTP版本為1.1版本,狀态碼為200,狀态消息為(ok)

第二部分:消息報頭,用來說明用戶端要使用的一些附加資訊

第二行和第三行為消息報頭,

Date:生成響應的日期和時間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8

第三部分:空行,消息報頭後面的空行是必須的

第四部分:響應正文,伺服器傳回給用戶端的文本資訊。

空行後面的html部分為響應正文。

Code

狀态代碼有三位數字組成,第一個數字定義了響應的類别,共分五種類别:

1xx:訓示資訊–表示請求已接收,繼續處理

2xx:成功–表示請求已被成功接收、了解、接受

3xx:重定向–要完成請求必須進行更進一步的操作

4xx:用戶端錯誤–請求有文法錯誤或請求無法實作

5xx:伺服器端錯誤–伺服器未能實作合法的請求

常見狀态碼:

OK                        // 用戶端請求成功
 Bad Request               // 用戶端請求有文法錯誤,不能被伺服器所了解
 Unauthorized              // 請求未經授權,這個狀态代碼必須和WWW-Authenticate報頭域一起使用
 Forbidden                 // 伺服器收到請求,但是拒絕提供服務
 Not Found                 // 請求資源不存在,eg:輸入了錯誤的URL
 Internal Server Error     // 伺服器發生不可預期的錯誤
 Server Unavailable        // 伺服器目前不能處理用戶端的請求,一段時間後可能恢複正常
           

Method

根據HTTP标準,HTTP請求可以使用多種請求方法。

HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

GET     請求指定的頁面資訊,并傳回實體主體。
HEAD     類似于get請求,隻不過傳回的響應中沒有具體的内容,用于擷取報頭
POST     向指定資源送出資料進行處理請求(例如送出表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導緻新的資源的建立和/或已有資源的修改。
PUT     從用戶端向伺服器傳送的資料取代指定的文檔的内容。
DELETE      請求伺服器删除指定的頁面。
CONNECT     HTTP/協定中預留給能夠将連接配接改為管道方式的代理伺服器。
OPTIONS     允許用戶端檢視伺服器的性能。
TRACE     回顯伺服器收到的請求,主要用于測試或診斷。
           

Header

HTTP消息由用戶端到伺服器的請求和伺服器到用戶端的響應組成。請求消息和響應消息都是由開始行(對于請求消息,開始行就是請求行,對于響應消息,開始行就是狀态行),消息報頭(可選),空行(隻有CRLF的行),消息正文(可選)組成。

HTTP消息報頭包括普通報頭、請求報頭、響應報頭、實體報頭。

每一個報頭域都是由名字+“:”+空格+值 組成,消息報頭域的名字是大小寫無關的。

網絡請求庫

下面介紹幾個常見的Android http網路開發的工具庫。

URLConnection

URLConnection是Java JDK中自帶的網絡請求類,使用的場景不多,因為使用比較繁瑣,直接使用底層IO流進行開發,需要了解Http協定才能很好的使用,很多時候需要自己封裝,不友善。一般的一些提供第三方服務的sdk會使用,一是為了保證sdk體積大小,二是減少不必要的第三方庫引入。

這裡不做詳細介紹, 這裡有一篇博可以詳細介紹了 。

Apache HttpClient

HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支援HTTP協定的用戶端程式設計工具包,并且它支援HTTP協定最新的版本和建議。HttpClient已經應用在很多的項目中,比如Apache Jakarta上很著名的另外兩個開源項目Cactus和HTMLUnit都使用了HttpClient。

HttpClient相比傳統JDK自帶的URLConnection,增加了易用性和靈活性,它不僅是用戶端發送Http請求變得容易,而且也友善了開發人員測試接口(基于Http協定的),即提高了開發的效率,也友善提高代碼的健壯性。

Android在低版本的系統Api中也有Httpclient相關類,但是後來就已經廢棄,相關資料可以 參考這裡.

HttpClient相關部落格

Volley

Android Volley 是在2013年Google I/O大會上推出了一個新的網絡通信架構——Volley。Volley可是說是把AsyncHttpClient和Universal-Image-Loader的優點集于了一身,既可以像AsyncHttpClient一樣非常簡單地進行HTTP通信,也可以像Universal-Image-Loader一樣輕松加載網絡上的圖檔。除了簡單易用之外,Volley在性能方面也進行了大幅度的調整,它的設計目标就是非常适合去進行資料量不大,但通信頻繁的網絡操作,而對于大資料量的網絡操作,比如說下載下傳檔案等,Volley的表現就會非常糟糕。

有 資料 指出Volley在進行網絡請求時,在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。主要是因為HttpURLConnection存在相關bug。

Volley相關資料

Volley相關資料

OkHttp & Retrofit

OkHttpSquare公司開源的處理網絡請求的開源項目,是安卓端最火熱的輕量級架構,用于替代HttpUrlConnection和Apache HttpClient。最新的版本是OkHttp3,Github位址在 這裡 。

Retrofit也是是Square公司開發的一款針對Android網絡請求的架構,Retrofit2底層基于OkHttp實作的,OkHttp現在已經得到Google官方認可,大量的app都采用OkHttp做網絡請求, Github位址 。

網絡上也有很多關于OkHttp、Retrofit的示例和資料,而且是目前Android移動端最流行的架構,還是很值得了解一下,在這裡就不做詳細介紹。

工具

Charles

Charles是一個HTTP代理伺服器,HTTP螢幕,反轉代理伺服器·它允許一個開發者檢視所有連接配接網際網路的HTTP通信·這些包括request、response、headers(包含cookies與caching資訊),由于筆者的開發機器是Mac,是以隻介紹了Charles,Windows開發環境的同學可以使用fiddler。

Charles介紹

Charles 主要的功能包括:

截取 Http 和 Https 網絡封包。

支援網絡請求調試,設定斷點,友善調試

支援重發網絡請求,友善後端調試。

支援修改網絡請求參數。

支援網絡請求的截獲并動态修改。

支援模拟弱網。

上面介紹了,可以使用Charles友善設定斷點,友善調試,可以很容易的修改資料包,這樣可以動态修改資料,mock api接口,在實際開發過程中很有用。

Charles Mock 資料

PostMan & Paw

上面介紹了網絡抓包工具Charles,先介紹2款模拟http請求的軟體。

Postman是一款功能強大的網頁調試與發送網頁HTTP請求的Chrome插件,使用很簡單。

下圖模拟發送知乎Api的網絡請求。

http://news-at.zhihu.com/api/4/themes

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

Postman官網

Postman資料

Paw 也是類似于Postman的一款模拟http請求的軟體,隻不過postman依賴于chrome,經常需要點選2此才可以打開postman,是以個人更加喜歡paw,下圖是paw請求知乎api的示例。BTW, paw是一款收費的軟體,不過麼網上也有破解的,在這裡就不介紹如何擷取了,反正大家都懂的。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

Paw 官網

Paw 使用教程

Chrome Dev Tools

Chrome dev tools是Google Chrome浏覽器中自帶一塊調試工具。如果你是做軟體開發的,基本都了解過。

雖然Chrome dev tools 在web開發中使用很多,但是在移動端中也是有用到的,這個後面再介紹。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

Chrome dev tools 相關資料

Chrome dev tools 相關資料

Chrome dev tools 相關資料

curl

curl也是和上面poastman與paw功能類似的,不過沒有和上面兩款放在一起講是因為curl比較重要,而且具有統一标準性與友善性。

curl是利用URL文法在指令行方式下工作的開源檔案傳輸工具。它被廣泛應用在Unix、多種Linux發行版中,并且有DOS和Win32、Win64下的移植版本。

還是原先的例子,請求知乎的api。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

很簡單在curl指令直接加入url即可發送網絡請求。

為什麼有postman和paw這麼友好的軟體後,還需要介紹的curl呢,因為curl是一個指令,是文本,是字元串,當你其他同僚開發聯調的時候,直接通過im工具發送即可,這樣網絡請求就能很容移動複現。很多的上面介紹的charles、paw、google dev tool都支援把某一條請求導出為curl指令。這就相當于curl是一個标準,可以在不同機器上面複用,是以了解和使用curl是很有必要的。比如聯調開發時候,伺服器某個api調試不通過,需要與伺服器同學溝通與複習,你直接丢一個curl語句即可,如果對方很懂,那麼會覺的你很專業,如果對方不懂,順便可以裝個逼。

curl 資料

curl 官網

OkHttp相關

前面介紹了OkHttp,下面介紹幾個基于OkHttp攔截器機制衍生出的常用的工具。

logging-interceptor

開發中經常需要對網絡請求進行檢視,抓包是可以的,不過現在很多app都是全棧https,想要抓包就沒有那麼容易了,那麼最簡單的還是打日志。

logging-interceptor

就是幹這個事的,在初始化okhttpclient的時候,添加下這個攔截器,那麼所有的網絡請求會被記錄下來。

相關資料

相關資料

Stetho

Stetho是Facebook開源的一個工具,前面說過Google Chrome dev tools,那麼Stetho可以讓Chrome調試Android,監控網絡請求。

同時Stetho還支援檢視資料庫,SharePreference等,而這個前提是必須root,檢視view樹,使用Stetho也可以做到。

網上也有很多也有很多相關資料,這裡不介紹詳細使用。

stetho github

stetho 相關資料

chuck

上面介紹的兩款工具,一種是需要在logcat中檢視網絡請求資料,一種是需要在chrome中檢視資料,有沒有辦法不需要借助任何第三方工具,直接檢視呢,答案是肯定的。chuck是我最近關注比較高的一個開源工具,而且很快的就在項目中使用了。

下面官網的截圖,可以先了解下chuck的使用效果。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

在高版本的Android中,還支援多屏顯示,那麼一邊操作一邊顯示。

Android Http網絡開發神兵利器Android Http網絡開發神兵利器Http協定網絡請求庫工具OkHttp相關其他總結參考資料

內建的方法都很簡單,隻需要在初始化OkHttpClient的時候,添加對應的攔截器即可。

Gradle依賴

dependencies {
   debugCompile 'com.readystatesoftware.chuck:library:1.0.4'
   releaseCompile 'com.readystatesoftware.chuck:library-no-op:1.0.4'
 }
           

添加攔截器

OkHttpClient client = new OkHttpClient.Builder()
  .addInterceptor(new ChuckInterceptor(context))
  .build();
           

Chuck github

其他

RESTful

RESTful一種軟體架構風格,設計風格而不是标準,隻是提供了一組設計原則和限制條件。它主要用于用戶端和伺服器互動類的軟體。基于這個風格設計的軟體可以更簡潔,更有層次,更易于實作緩存等機制。

REST(英文:Representational State Transfer,簡稱REST)描述了一個架構樣式的網絡系統,比如 web 應用程式。它首次出現在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規範的主要編寫者之一。在目前主流的三種Web服務互動方案中,REST相比于SOAP(Simple Object Access protocol,簡單對象通路協定)以及XML-RPC更加簡單明了,無論是對URL的處理還是對Payload的編碼,REST都傾向于用更加簡單輕量的方法設計和實作。值得注意的是REST并沒有一個明确的标準,而更像是一種設計的風格。

雖然本文的主題是介紹Android Http開發的相關内容,并且RESTful是服務端的一種概念。但是我覺的,還是有很必要了解的,最起碼可以作為判斷你的服務端小夥伴給的接口是否滿足RESTful的标準的依據。

後面貼一篇阮一峰大神的部落格介紹RESTful

總結

心得

上面介紹了很多種關于網絡請求的工具,具體可以分為這幾類。

HTTP接口調用工具,這類工具主要是模拟用戶端,發起網絡請求,友善調試伺服器接口。

  • postman
  • paw
  • curl

抓包工具,這類工具不光适合Android開發,也适合其他網絡開發,工具使用簡單,不過在使用前需要做少許代理配置。WiresShark是一款更加強大的工具,使用比較複雜,而且比較底層,是以在本文中就沒介紹,有興趣的同學可以自己查閱相關資料。

  • Charles
  • Fiddler
  • WiresShark

Android Http請求工具庫,這類工具類變化很快,經常會過個幾年就會有新的一種工具替換,但是本質思想還是一樣的,都是基于URLConnection和HTTP做了一次封裝調用。

  • URLConnection
  • HttpClient
  • Volley
  • OkHttp

OkHttp相關,這類工具都是基于OkHttp做了二次封裝開發,這個主要歸功于OkHttp強大開發模式和架構,開發人員可以友善對OkHttp進行自定義和二次開發。工具很強大,不過也有局限性,隻能依附于OkHttp的架構,不利于擴充到其他平台和工具。

  • logging-interceptor
  • Stetho
  • Chuck

工具對比

上面介紹好幾款可以監控App網絡請求的工具,那麼如何根據實際情況,選擇一款适合自己項目和團隊的工具呢?

Charles & Fiddler

這類工具不依賴與平台和App開發的工具庫,不管你是Android、還是iOS,不管使用的是Volley,還是OkHttp都是可以監控的,同時還支援HTTP的調試,友善mock資料,簡直是神器。

不過也有少許缺點,比如是不支援Https,如果你的app使用的是https接口,那麼這類工具一般情況是不能使用的,不過也有辦法,比如把charles的證書設定為根證書,則可以檢測到。但是也是有局限的,如果app設定強制校驗https證書,此類方法還是不可行。

因為平台無光,可檢測到某個手機裝置上面的全部網絡請求,資料量有時候會很大,如果經常調試某一個app,那麼域名一般是固定的,可進行相對應的過濾。

OkHttp相關

通過标題可以看成,此類工具必須依附于OKHttp,那麼隻能滿足Android平台并且App的網絡請求庫是OkHttp。上面介紹的三款工具,可以選擇性的選擇其中幾種或者是全部,暫時還沒有發現沖突的地方。因為是直接嵌入到代碼中,那麼Https也是可以監控到。同時也隻能監控目前裝置上的目前應用,不可以檢測其他的app。

不過在釋出線上或者正式頒布時,需要手動去除這些代碼,否則會有很大麻煩,同時也會把相關的隐私和安全回報給使用的使用者。

好了,上面就是關于App網絡情況的監控工具比較,建議兩個大分類都可以幾個或者多個配合使用,具體問題在根據具體工具使用,友善問題解決與網絡監控。

其他建議

上面介紹的OkHttp的相關的工具,都是需要在初始化OkHttpClient的時候,手動添加對應的攔截器,如果忘記添加則不會産生效果。

那麼可以使用現在流行的Aop技術,在編譯時候,會在所有調用OkHttpClient的地方,自動添加,保證不會忘記,如果你的App還是用其他的sdk,sdk裡面也是用OKhttp的話,也會監控到sdk裡面的網絡請求,不少大廠已經使用了這種方法,然後收集請求資料到後端,友善管理和優化。

下面簡單介紹相關代碼:

首先內建

gradle_plugin_android_aspectjx

插件

dependencies {
    classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.9'
}
           

然後定義Aspectj切入點

import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.readystatesoftware.chuck.ChuckInterceptor;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import me.ele.breakfastapp.AppContext;
import okhttp3.OkHttpClient;

@Aspect
public class OkHttpAspect {

    @Pointcut("call(public okhttp3.OkHttpClient build())")
    public void build() {
    }

    @Around("build()")
    public Object aroundBuild(ProceedingJoinPoint joinPoint) throws Throwable {
        Object target = joinPoint.getTarget();
        if (target instanceof OkHttpClient.Builder) {
            OkHttpClient.Builder builder = (OkHttpClient.Builder) target;
            builder.addNetworkInterceptor(new StethoInterceptor());
            builder.addNetworkInterceptor(new ChuckInterceptor(AppContext.get()));
        }

        return joinPoint.proceed();
    }
}
           

那麼在代碼編譯的時候,會自動插入位元組碼。

Aop相關資料:

Aop介紹

Aop資料

Assectj

Assectj Gradle 插件

參考資料

Http部落格

Http部落格

URLConnection

Android HttpClient

HttpClient相關部落格

Volley相關資料

Volley相關資料

OkHttp

Retrofit Github位址

Charles介紹

Charles Mock 資料

Postman官網

Postman資料

Paw 官網

Paw 使用教程

Chrome dev tools 相關資料

Chrome dev tools 相關資料

Chrome dev tools 相關資料

curl 資料

curl 官網

Interceptors相關資料

LoggingInterceptors相關資料

stetho github

stetho 相關資料

Chuck github

RESTful

Aop介紹

Aop資料

Assectj

Assectj Gradle 插件