Retrofit使用方法
官網:http://square.github.io/retrofit/
首先需要添加訪問網絡的權限。
<uses-permission android:name="android.permission.INTERNET"/>
去官網添加最新依賴
compile
'com.squareup.retrofit2:retrofit:2.0.1'
創建API接口
在retrofit中通過一個Java接口作爲http請求的api接口。注:GET括號裏面的是相對路徑。Path括號裏面的是對應Get括號的參數
public interface GitHubApi {
@GET("repos/{owner}/{repo}/contributors")
Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
}
創建retrofit實例
在這裏baseUrl是在創建retrofit實力的時候定義的,我們也可以在API接口中定義完整的url。在這裏建議在創建baseUrl中以”/”結尾,在API中不以”/”開頭和結尾。
構建根url
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
之後就可以直接調用生成的GitHubServcie
實例去發送同步或異步的請求給Web服務器
Call<List<Repo>> repos = service.listRepos("octocat");
API 聲明
接口函數的註解和參數表明如何去處理請求
請求方法
每一個函數都必須有提供請求方式和相對URL的Http註解,Retrofit提供了5種內置的註解:GET
、POST
、PUT
、DELETE
和HEAD
,在註解中指定的資源的相對URL
@GET("users/list")
- 1
- 1
也可以在URL中指定查詢參數
@GET("users/list?sort=desc")
URL處理
請求的URL可以在函數中使用替換塊和參數進行動態更新,替換塊是{ and }
包圍的字母數字組成的字符串,相應的參數必須使用相同的字符串被@Path
進行註釋
@GET("group/{id}/users")
List<User> groupList(@Path("id") int groupId);
- 1
- 2
- 1
- 2
也可以添加查詢參數
@GET("group/{id}/users")
List<User> groupList(@Path("id") int groupId, @Query("sort") String sort);
- 1
- 2
- 1
- 2
複雜的查詢參數可以使用Map
進行組合
@GET("group/{id}/users")
List<User> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
請求體
可以通過@Body
註解指定一個對象作爲Http請求的請求體
@POST("users/new")
Call<User> createUser(@Body User user);
- 1
- 2
- 1
- 2
該對象將會被Retroofit
實例指定的轉換器轉換,如果沒有添加轉換器,則只有RequestBody
可用。(轉換器的添加在後面介紹)
FORM ENCODED 和 MULTIPART
函數也可以聲明爲發送form-encoded
和multipart
數據。
當函數有@FormUrlEncoded
註解的時候,將會發送form-encoded
數據,每個鍵-值對都要被含有名字的@Field
註解和提供值的對象所標註
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
- 1
- 2
- 3
- 1
- 2
- 3
當函數有@Multipart
註解的時候,將會發送multipart
數據,Parts都使用@Part
註解進行聲明
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
- 1
- 2
- 3
- 1
- 2
- 3
Multipart parts要使用Retrofit的衆多轉換器之一或者實現RequestBody
來處理自己的序列化。
Header處理
可以使用@Headers
註解給函數設置靜態的header
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
- 1
- 2
- 3
- 1
- 2
- 3
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
需要注意的是:header不能被互相覆蓋。所有具有相同名字的header將會被包含到請求中。
可以使用@Header
註解動態的更新一個請求的header。必須給@Header
提供相應的參數,如果參數的值爲空header將會被忽略,否則就調用參數值的toString()
方法並使用返回結果
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
Header處理
可以使用@Headers
註解給函數設置靜態的header
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
- 1
- 2
- 3
- 1
- 2
- 3
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
需要注意的是:header不能被互相覆蓋。所有具有相同名字的header將會被包含到請求中。
可以使用@Header
註解動態的更新一個請求的header。必須給@Header
提供相應的參數,如果參數的值爲空header將會被忽略,否則就調用參數值的toString()
方法並使用返回結果
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
Retrofit 配置
Retrofit
是通過API接口轉換成的可調用的對象,默認有一些合理的配置,這些配置也可以進行定製。
轉換器
默認情況下,Retrofit只能夠反序列化Http體爲OkHttp的ResponseBody
類型,並且只能夠接受ResponseBody
類型的參數作爲@body
。
添加轉換器可以支持其他的類型,爲了方便的適應流行的序列化庫,Retrofit提供了六個兄弟模塊:
- Gson : com.squareup.retrofit:converter-gson
- Jackson: com.squareup.retrofit:converter-jackson
- Moshi: com.squareup.retrofit:converter-moshi
- Protobuf: com.squareup.retrofit:converter-protobuf
- Wire: com.squareup.retrofit:converter-wire
- Simple XML: com.squareup.retrofit:converter-simplexml
自定義轉換器
如果需要使用Retrofit不支持開箱即用的內容格式(如YAML、txt、自定義格式)和API進行通信,或者想要使用不同的庫實現已經存在的格式,你可以很方便的創建自己的轉換器。創建方式:新建一個類繼承Converter.Factory類,並在構建Retrofit實例時傳入轉換器實例。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作爲回調適配器
.addConverterFactory(GsonConverterFactory.create()) // 使用Gson作爲數據轉換器
.build();
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
使用RxJava和Gson轉換器需要添加依賴
// Retrofit適配RxJava
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
// Retrofit Gson數據轉換器
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
配合RxJava使用
在Rxjava下,你可以用Observable定義異步函數:
@GET("user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);
- 1
- 2
- 1
- 2
現在你可以做很多事情,不光可以獲取數據還可以改變數據。
Retrofit 支持Observable導致了將多個REST調用組合在一起變得簡單了。例如,我們有一個調用去獲取照片,第二個調用去獲取原生數據,我們可以將結果一起打包。
Observable.zip(
service.getUserPhoto(id),
service.getPhotoMetadata(id),
(photo, metadata) -> createPhotoWithData(photo, metadata))
.subscribe(photoWithData -> showPhoto(photoWithData));
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
通過RxJava + Retrofit可以讓多個REST調用組合成一個變得更簡單。