天天看點

網絡請求架構 Retrofit 2 使用入門

<b>本文講的是網絡請求架構 Retrofit 2 使用入門,</b>

<b></b>

網絡請求架構 Retrofit 2 使用入門

你将要創造什麼

這個強大的庫可以很簡單的把傳回的 JSON 或者 XML 資料解析成簡單 Java 對象(POJO)。<code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, 和<code>DELETE</code> 這些請求都可以執行。

Gson: <code>com.squareup.retrofit:converter-gson</code>

Jackson: <code>com.squareup.retrofit:converter-jackson</code>

Moshi: <code>com.squareup.retrofit:converter-moshi</code>

Protobuf: <code>com.squareup.retrofit2:converter-protobuf</code>

Wire: <code>com.squareup.retrofit2:converter-wire</code>

對于 XML 解析, Retrofit 提供了:

Simple Framework: <code>com.squareup.retrofit2:converter-simpleframework</code>

開發一個自己的用于請求 REST API 的類型安全的網絡請求庫是一件很痛苦的事情:你需要處理很多功能,比如建立連接配接,處理緩存,重連接配接失敗請求,線程,響應資料的解析,錯誤處理等等。從另一方面來說,Retrofit 是一個有優秀的計劃,文檔和測試并且經過考驗的庫,它會幫你節省你的寶貴時間以及不讓你那麼頭痛。

網絡請求架構 Retrofit 2 使用入門

建立一個新的工程後,在你的 <code>build.gradle</code> 檔案裡面添加以下依賴。這些依賴包括 RecyclerView,Retrofit 庫,還有 Google 出品的将 JSON 裝換為 POJO(簡單 Java 對象)的 Gson 庫,以及 Retrofit 的 Gson。

不要忘記同步(sync)工程來下載下傳這些庫。

要執行網絡操作,我們需要在應用的清單檔案 AndroidManifest.xml 裡面聲明網絡權限。

網絡請求架構 Retrofit 2 使用入門

從你的浏覽器或者 Postman 複制 JSON 響應結果。

選擇 Source Type 為 JSON,Annotation Style 為 Gson,然後取消勾選 Allow additional properties。

網絡請求架構 Retrofit 2 使用入門

然後點選 Preview 按鈕來生成 Java 對象。

網絡請求架構 Retrofit 2 使用入門

你可能想知道在生成的代碼裡面, <code>@SerializedName</code> 和 <code>@Expose</code> 是幹什麼的。别着急,我會一一解釋的。

Gson 使用 <code>@SerializedName</code> 注解來将 JSON 的 key 映射到我們類的變量。為了與 Java 對類成員屬性的駝峰命名方法保持一緻,不建議在變量中使用下劃線将單詞分開。<code>@SerializeName</code> 就是兩者的翻譯官。

在上面的示例中,我們告訴 Gson 我們的 JSON 的 key <code>quota_remaining</code> 應該被映射到 Java 變量 <code>quotaRemaining</code>上。如果兩個值是一樣的,即如果我們的 JSON 的 key 和 Java 變量一樣是 <code>quotaRemaining</code>,那麼就沒有必要為變量設定<code>@SerializedName</code> 注解,Gson 會自己搞定。

<code>@Expose</code> 注解表明在 JSON 序列化或反序列化的時候,該成員應該暴露給 Gson。

現在讓我們回到 Android Studio。建立一個 data 的子包,在 data 裡面再建立一個 model 的包。在 model 包裡面,建立一個 Owner 的 Java 類。 然後将 jsonschema2pojo 生成的 <code>Owner</code> 類複制粘貼到剛才建立的 <code>Owner</code> 類檔案裡面。

利用同樣的方法從 jsonschema2pojo 複制過來,建立一個 <code>Item</code> 類。

最後,為傳回的 StackOverflow 回答建立一個 <code>SOAnswersResponse</code> 類。注意在 jsonschema2pojo 裡面類名是 <code>Example</code>,别忘記把類名改成 <code>SOAnswersResponse</code>。

在 <code>data</code> 包裡面建立一個 <code>remote</code> 的包,然後在 <code>remote</code> 包裡面建立一個 <code>RetrofitClient</code> 類。這個類會建立一個 Retrofit 的單例。Retrofit 需要一個 base URL 來建立執行個體。是以我們在調用 <code>RetrofitClient.getClient(String baseUrl)</code> 時會傳入一個 URL 參數。參見 13 行,這個 URL 用于建構 Retrofit 的執行個體。參見 14 行,我們也需要指明一個我們需要的 JSON converter(Gson)。

在 remote 包裡面,建立一個 <code>SOService</code> 接口,這個接口包含了我們将會用到用于執行網絡請求的方法,比如 <code>GET</code>, <code>POST</code>,<code>PUT</code>, <code>PATCH</code>, 以及 <code>DELETE</code>。在該教程裡面,我們将執行一個 <code>GET</code> 請求。

<code>GET</code> 注解明确的定義了當該方法調用的時候會執行一個 <code>GET</code> 請求。接口裡每一個方法都必須有一個 HTTP 注解,用于提供請求方法和相對的 <code>URL</code>。Retrofit 内置了 5 種注解:<code>@GET</code>, <code>@POST</code>, <code>@PUT</code>, <code>@DELETE</code>, 和 <code>@HEAD</code>。

在第二個方法定義中,我們添加一個 query 參數用于從服務端過濾資料。Retrofit 提供了 <code>@Query("key")</code> 注解,這樣就不用在位址裡面直接寫了。key 的值代表了 URL 裡參數的名字。Retrofit 會把他們添加到 URL 裡面。比如說,如果我們把 <code>android</code>作為參數傳遞給 <code>getAnswers(String tags)</code> 方法,完整的 URL 将會是:

接口方法的參數有以下注解:

@Path

替換 API 位址中的變量

@Query

通過注解的名字指明 query 參數的名字

@Body

POST 請求的請求體

@Header

通過注解的參數值指明 header

現在我們要建立一個工具類。我們命名為 <code>ApiUtils</code>。該類設定了一個 base URL 常量,并且通過靜态方法 <code>getSOService()</code>為應用提供 <code>SOService</code> 接口。

在 <code>MainActivity</code> 的 <code>onCreate()</code> 方法内部,我們初始化 <code>SOService</code> 的執行個體(參見第 9 行),RecyclerView 以及 adapter。最後我們調用 <code>loadAnswers()</code> 方法。

<code>loadAnswers()</code> 方法通過調用 <code>enqueue()</code> 方法來進行網絡請求。當響應結果傳回的時候,Retrofit 會幫我們把 JSON 資料解析成一個包含 Java 對象的 list(這是通過 <code>GsonConverter</code> 實作的)。

<code>enqueue()</code> 會發送一個異步請求,當響應結果傳回的時候通過回調通知應用。因為是異步請求,是以 Retrofit 将在背景線程處理,這樣就不會讓 UI 主線程堵塞或者受到影響。

要使用 <code>enqueue()</code>,你必須實作這兩個回調方法:

<code>onResponse()</code>

<code>onFailure()</code>

隻有在請求有響應結果的時候才會調用其中一個方法。

<code>onResponse()</code>:接收到 HTTP 響應時調用。該方法會在響應結果能夠被正确地處理的時候調用,即使伺服器傳回了一個錯誤資訊。是以如果你收到了一個 404 或者 500 的狀态碼,這個方法還是會調用。為了拿到狀态碼以便後續的處理,你可以使用 <code>response.code()</code> 方法。你也可以使用 <code>isSuccessful()</code> 來确定傳回的狀态碼是否在 200-300 範圍内,該範圍的狀态碼也表示響應成功。

<code>onFailure()</code>:在與伺服器通信的時候發生網絡異常或者在處理請求或響應的時候發生異常的時候調用。

要執行同步請求,你可以使用 <code>execute()</code> 方法。要注意同步請求在主線程會阻塞使用者的任何操作。是以不要在主線程執行同步請求,要在背景線程執行。

現在你可以運作應用了。

網絡請求架構 Retrofit 2 使用入門

如果你是 RxJava 的粉絲,你可以通過 RxJava 很簡單的實作 Retrofit。RxJava 在 Retrofit 1 中是預設整合的,但是在 Retrofit 2 中需要額外添加依賴。Retrofit 附帶了一個預設的 adapter 用于執行 <code>Call</code> 執行個體,是以你可以通過 RxJava 的 <code>CallAdapter</code> 來改變 Retrofit 的執行流程。

添加依賴。

在建立新的 Retrofit 執行個體的時候添加一個新的 CallAdapter <code>RxJavaCallAdapterFactory.create()</code>。

當我們執行請求時,我們的匿名 subscriber 會響應 observable 發射的事件流,在本例中,就是 <code>SOAnswersResponse</code>。當 subscriber 收到任何發射事件的時候,就會調用 <code>onNext()</code> 方法,然後傳遞到我們的 adapter。

在該教程裡,你已經了解了使用 Retrofit 的理由以及方法。我也解釋了如何将 RxJava 結合 Retrofit 使用。在我的下一篇文章中,我将為你展示如何執行 <code>POST</code>, <code>PUT</code>, 和 <code>DELETE</code> 請求,如何發送 <code>Form-Urlencoded</code> 資料,以及如何取消請求。

<b>原文釋出時間為:2016年12月26日</b>

<b>本文來自雲栖社群合作夥伴掘金,了解相關資訊可以關注掘金網站。</b>