[譯] Retrofit官方文件最佳實踐

莫比烏斯環發表於2018-10-12

Retrofit

Retrofit官方文件翻譯(原文連結:http://square.github.io/retrofit/) 本文翻譯純屬學習筆記記錄,如有涉及到版權問題請郵件(itingchunyu@163.com)我,我會立即撤銷展示,謝謝!

介紹

Retrofit 改造你的HTTP API變成一個Java介面。

public interface GitHubService {
	@Get("users/{user}/repos")
	Call<List<Repo>> listRepos(@Path("user") String user)
}
複製程式碼

Retrofit 類生成一個 GitHubService 介面的實現。

Retrofit retrofit = new Retrofit.Builder()
	.baseUrl("https://api.github.com/") //可動態配置
	.build();
//生成指定介面的實現	
GitHubService service = retrofit.create(GitHubService.class);	
複製程式碼

GitHubService建立的每個 Call 可以同步或非同步HTTP請求到遠端網路伺服器。

Call<List<Repo>> repos = service.listRepos("octocat");
複製程式碼

使用註解去描述HTTP請求方式:

  • URL中引數支援根據傳入的查詢引數動態呼叫替換
  • 物件與請求實體的轉換(如:JSON,protocol buffers)
  • 多請求實體和檔案上傳支援

API 宣告

介面方法通過註解的方式及其引數指示如何處理一個請求

請求方式

每個方法必須擁有一個 HTTP 註解,去告知請求方式和相關呼叫Api。這裡有五種構造方式:GET, POST, PUT, DELETE, and HEAD.相關資源的URL被指定在註釋中。

@GET("users/list")
複製程式碼

你也可以在URL中指定查詢引數。

@GET("users/list?sort=desc")
複製程式碼

URL相關操作

在方法中使用替換塊和引數可以動態更新一個請求的URL。一個替換塊是一個字母數字字串包圍{}。相應的引數必須與@path註釋使用相同的字串標記。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
複製程式碼

查詢引數也可以被新增。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
複製程式碼

對於複雜的查詢引數,引數可以存放 Map 集合中。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
複製程式碼

請求 BODY

使用@Body註釋一個物件,這個物件可以作為HTTP請求實體傳輸。

@POST("users/new")
Call<User> createUser(@Body User user);
複製程式碼

通過Retrofit例項初始化指定轉換器,如此這個被註釋的物件就可以被轉換。如果初始化未指定,預設的RequestBody被使用。

表單編碼和多部分提交

請求方法也可以被宣告傳送表單編碼和多部分資料方式提交。

@FormUrlEncoded 註釋出現在方法上,意味著請求以表單變編碼方式提交。因此每個key-value鍵值對引數必須被@Field標記註釋,包含名稱和對應的值。

@FormUrlEncoded
@POST("user/edit")
Call<User> update(@Field("first_name") String first, @Field("last_name") String last);
複製程式碼

Multipart requests are used when @Multipart is present on the method. Parts are declared using the @Part annotation.

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
複製程式碼

請求Headers引數設定

你可以根據需要在一個方法上使用@Headers設定靜態的頭引數配置。

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
複製程式碼
@Headers({
	"Accept: application/vnd.github.v3.full+json",
	"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
複製程式碼

注意,Headers不會互相覆蓋。具有相同名稱的所有標頭檔案都包括在請求。一個請求的Headers可以動態更新。通過@Header註釋相關引數傳入。如果傳入的值為空,這個header將會被忽略。否則toString方法將會被呼叫並且結果將被使用。

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization);
複製程式碼

Headers可以使用OkHttp interceptor為每個請求統一指定headers。

同步Vs非同步

Call 事例能被同步或非同步執行。每個事例僅僅能被使用一次,但是呼叫clone()方法可以建立一個副本可以被重新使用。 在Android裡面,回撥執行在主執行緒。在Java虛擬機器中,回撥將會發生在與發起HTTP請求同一個執行緒中。

Retrofit配置

Retrofit是一種能將你的API介面轉化為可呼叫的物件的類。預設情況下,Retrofit會給你預設配置項,但它允許你自己定製。

轉換器

預設情況下,Retrofit可以反序列化HTTP bodyies為OkHttp的ResponseBody型別,並且它只接受RequestBody實體為@Body註釋的型別。 轉換器也可以新增其它型別支援。六個模組適應現下主流的序列化庫為你提供方便。

  • Gson:com.squareup.retrofit2:converter-gson
  • Jackson:com.squareup.retrofit2:converter-jackson
  • Moshi:com.squareup.retrofit2:converter-moshi
  • Protobuf:com.squareup.retrofit2:converter-protobuf
  • Wire:com.squareup.retrofit2:converter-wire
  • Simple XML:com.squareup.retrofit2:converter-simplexml
  • [Scalars](primitives,boxed,and String):com.squareup.retrofit2:converter-scalars

下面是一個使用GsonConverterFactory類生成GitHubService介面的實現的示例,該介面使用Gson進行反序列化。

Retrofit retrofit = new Retrofit.Builder()
	.baseUrl("https://api.github.com")
	.addConverterFactory(GsonCoverterFactory.create())
	.build();
GitHubService service = retrofit.create(GitHubService.class);
複製程式碼

自定義轉換器

如果您需要使用Retrofit不支援的內容格式(例如YAML,txt,自定義格式)的API進行通訊,或者您希望使用不同的庫來實現現有的格式,則可以輕鬆地建立你自己的轉換器。 建立一個擴充套件了Converter.Factory類的類,並在構建介面卡時傳遞一個例項。

Download

V2.3.0 JAR

Retrofit的原始碼、事例你可以在GitHub上查閱。

Maven

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.3.0</version>
</dependency>
複製程式碼

Gradle依賴

compile 'com.squareup.retrofit2:retrofit:2.3.0'
複製程式碼

Retrofit要求最小Java7或Android 2.3.

混淆機制

如果你使用在你的專案中使用ProGuard,你應該在你的混淆檔案配置中新增下面對應混淆程式碼:

# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
複製程式碼

Retrofit的底層使用Okio,所以你或許也需要了解ProGuard rules混淆規則。


License

Copyright 2013 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
複製程式碼

相關文章