簡介
Retrofit可以將你的HTTP API轉換成Java接口。
public interface GitHubService{
@GET("user/{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參數佔位符和查詢參數
- Object轉換爲請求體(例如:JSON,結構化數據)
- Multipart請求體和文件上傳
API聲明
在接口的方法和方法的形參上的註釋,起作用是用來指明一個請求將要如何被處理的。
請求方法
每一個方法必須要有一個用來提供請求方法和相關URL的HTTP註釋。有五個固定的註釋:GET,POST,PUT,DELETE,HEAD
。註釋中要指定請求的資源對應的URL:
@GET("users/list")
你也可以在URL中指定查詢參數:
@GET("users/list?sort=desc")
URL處理
你可以在方法上使用佔位塊和參數來動態的修改URL。佔位塊是被{}
括起來的數字和字符混合的String
類型數據。對應的參數必須被@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
註釋的對象可以被指定作爲HTTP請求體使用:
@POST("user/new")
Call<User> createUser(@Body User user);
當使用一個被Retrofit
實例指定的Converter
時,這個對象也將會被修改。如果沒有添加converter
,那麼只有RequestBody
可以被使用。
FORM ENCODED 和 MULTIPART
方法也可以被聲明成用來發送表格數據和Multipart數據。
當方法上被@FormUrlEncoded
註釋的時候,Form-encoded數據會被髮送。每一個鍵值對需要被@Field
修飾,它包含了name和value:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
可以在方法上加上@Multipart
註釋來發送Multipart請求。Parts需要使用@Part
註釋:
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Multipart parts使用Retrofit
衆多的convert
中的一個,或者可以自己實現一個RequestBody
來處理自己的序列化。
請求頭的處理
你可以使用@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);
注意,hearders彼此之間互不干擾。有着相同名字的所有headers將會被請求包含。
可以使用@Header
動態的修改一個Header。@Header
後面必須跟着相應的參數。如果參數的值爲null,那麼這個Header將會被忽視。否則,value 的toString
方法會被調用,並且會被作爲結果使用。
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
需要被添加到每次請求的Header可以用OkHttp Interceptor指定。
同步VS異步
Call
可以異步執行,也可以同步執行。每一個實例只可以被使用一次,但是調用clone()
可以生成一個新的可以使用的實例。
在Android中,callbacks
會在主線程中執行,在JVM中,callbacks
會在執行HTTP請求的那個線程中執行。(譯者注:直接調用excute
方法爲同步執行,調用enqueue
方法爲異步執行。)
Retrofit配置
Retrofit
可以將你的API接口轉換爲可調用的對象。默認情況下,Retrofit
會爲你的平臺提供匹配的默認值,但是它同樣允許定製。
CONVERTERS
默認情況下,Retrofit只能將HTTP body解析成OkHttp的ResponseBody
類型,並且@Body
只接受OkHttp的RequestBody
類型。
爲了可以支持其他類型,converters允許被添加。爲了你的方便,Retrofit已經適配了六個流行的解析庫:
- 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
下面是一個例子,使用GsonConvertFactory
來生成接口GitHubService
的實現,其中接口GitHubService
是使用Gson來解析數據的。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
自定義CONVERTERS
如果你需要使用Retrofit不支持的內容格式和API通信,或者你希望使用一個不同的庫來解析已經存在的格式,你可以簡單的創建自己的converter。創建一個類,使其繼承Converter.Factory
,當創建retrofit的時候將自己的converter作爲參數傳進去即可。
Download
MAVEN
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>(insert latest version)</version>
</dependency>
GRADLE
compile 'com.squareup.retrofit2:retrofit:(insert latest version)'
Retrofit最低支持Java7 或Android2.3。
PROGUARD
如果你的項目裏使用了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。