簡介
Retrofit 將你的HTTP API轉(zhuǎn)換成java接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
用Retrofit class 創(chuàng)建一個(gè)實(shí)現(xiàn)了GitHubService 接口的對象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
每個(gè)被GitHubService創(chuàng)建的Call能發(fā)出一個(gè)同步或異步的http請求
Call<List<Repo>> repos = service.listRepos("octocat");
使用注解來描述HTTP請求
- URL支持參數(shù)替換和查詢參數(shù)
- 對象轉(zhuǎn)出成請求體(例如json protocol buffers)
- 多部分請求體和文件上傳
API聲明
根據(jù)在方法和參數(shù)聲明上的注解太防,一個(gè)請求會(huì)怎么被操作
請求Method
每個(gè)方法必須有個(gè)用來提供請求方式和相關(guān)的URL的HTTP注解,有5個(gè)內(nèi)置注解:GET,POST,PUT,DELETE和HEAD,關(guān)聯(lián)資源的URL在注解中指定
@GET("users/list")
You can also specify query parameters in the URL.
你也能指定在URL中的參數(shù)
@GET("users/list?sort=desc")
URL處理
一個(gè)URL請求能夠使用替換塊和和方法中的參數(shù)更新酸员,一個(gè)替換塊是一個(gè)被{}包裹的字符串蜒车。對應(yīng)的參數(shù)必須被用@path使用相同的字符串注解
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
查詢參數(shù)也能這樣被添加
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
至于復(fù)雜的查詢參數(shù),能夠結(jié)合map使用
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
Request Body
@Body 注釋一個(gè)對象能被指定作為一個(gè)HTTP請求體。
@POST("users/new")
Call<User> createUser(@Body User user);
在Retrofit實(shí)例中使用一個(gè)轉(zhuǎn)換器幔嗦,可以將一個(gè)對象轉(zhuǎn)換酿愧,如果沒有轉(zhuǎn)換器被添加,則只能使用RequestBody
multipart/form-data
方法也能聲明成multipart/form-data
當(dāng)@FormUrlEncoded 出現(xiàn)在方法上是form-data
每個(gè)鍵值對是用@Field注解的邀泉,包含了名字以及對應(yīng)的值
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
當(dāng)@Multipart出現(xiàn)在method中時(shí)嬉挡,Multipart請求被使用。
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Multipart parts要使用Retrofit的眾多轉(zhuǎn)換器之一或者實(shí)現(xiàn)RequestBody來處理自己的序列化汇恤。
Header處理
你能使用@Headers設(shè)置靜態(tài)的headler
@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);
注意:header是不會(huì)相互覆蓋的庞钢,所有使用相同名字的header都會(huì)被包含在請求中
一個(gè)請求的Header能被動(dòng)態(tài)更新,通過使用@Header因谎。@Header對應(yīng)的參數(shù)必須被提供基括,否則參數(shù)的toString會(huì)被調(diào)用并使用其返回值
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
可以使用Okhttp 攔截器頭添加每個(gè)請求都需要添加的header
同步和異步
Call對象 以同步或是異步的方式被執(zhí)行,每個(gè)對象僅能被執(zhí)行一次风皿,但是可以調(diào)用clone創(chuàng)建一個(gè)能被使用的新對象
在Android中河爹,callback在主線程中被執(zhí)行桐款,在JVM中,callback會(huì)在其發(fā)送HTTP請求的線程中
Retrofit配置
Retrofit是一個(gè)類魔眨,通過它將你的API接口轉(zhuǎn)換成可調(diào)用的對象媳维,默認(rèn)的遏暴,Retrofit會(huì)為根據(jù)你的平臺(tái)給一些合適的默認(rèn)值,但是它也允許你自定義
轉(zhuǎn)換器
默認(rèn)的拓挥,Retrofit只能將HTTP bodies 反序列化成OkHttp的ResponseBody類型并且它只能接受它自己的RequestBody類型作為參數(shù)。通過添加轉(zhuǎn)化器能夠支持其它的類型
為了方便你適配常用的序列化哭侥啤,提供了6個(gè)兄弟模塊
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
這兒有一個(gè)使用GsonConverterFactory產(chǎn)生一個(gè)實(shí)現(xiàn)了GitHubService接口的對象的例子,這個(gè)接口使用Gson來反序列化
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
自定義轉(zhuǎn)換器
如果需要使用Retrofit不支持的開箱即用的內(nèi)容格式(如YAML盖灸、txt、自定義格式)和API進(jìn)行通信或者使用一個(gè)不同的庫去實(shí)現(xiàn)一個(gè)已經(jīng)存在的格式赁炎,你能很容易的創(chuàng)造一個(gè)你自己的轉(zhuǎn)換器醉箕。通過創(chuàng)建一個(gè)繼承了[Converter.Factoryclass]的類,并且傳遞一個(gè)實(shí)例當(dāng)你構(gòu)建你的適配器時(shí)
.