簡介
Retrofit是由Square公司出品的針對Android和Java的類型安全的Http客戶端,網絡服務基于OkHttp 。
Retrofit2.0: 有史以來最大的改進
使用Retrofit2.0
下載 v2.0.0-beta2 JAR
Gradle :
compile com.squareup.retrofit:retrofit:2.0.0-beta2
Maven :
<dependency> <groupId>com.squareup.retrofitgroupId> <artifactId>retrofitartifactId> <version>2.0.0-beta2version> dependency>
用法介紹
轉換HTTP API為Java接口
public interface GitHubService { @GET("/users/{user}/repos")
CalllistRepos(@Path("user") String user);
}
使用類Retrofit生成接口GitHubService的實現
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .build() GitHubService service = retrofit.create(GitHubService.class)
以后就能夠直接調用生成的GitHubServcie實例去發送同步或異步的要求給Web服務器
Callrepos = service.listRepos("octocat");
API 聲明
接口函數的注解和參數表明如何去處理要求
要求方法
每個函數都必須有提供要求方式和相對URL的Http注解,Retrofit提供了5種內置的注解:GET、POST、PUT、DELETE和HEAD,在注解中指定的資源的相對URL
@GET("/users/list")
也能夠在URL中指定查詢參數
@GET("/users/list?sort=desc")
URL處理
要求的URL可以在函數中使用替換塊和參數進行動態更新,替換塊是{ and }包圍的字母數字組成的字符串,相應的參數必須使用相同的字符串被@Path進行注釋
@GET("/group/{id}/users") ListgroupList(@Path("id") int groupId);
也能夠添加查詢參數
@GET("/group/{id}/users")
ListgroupList(@Path("id") int groupId, @Query("sort") String sort);
復雜的查詢參數可使用Map進行組合
@GET("/group/{id}/users") ListgroupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
要求體
可以通過@Body注解指定1個對象作為Http要求的要求體
@POST("/users/new") Call<User> createUser(@Body User user);
該對象將會被Retroofit實例指定的轉換器轉換,如果沒有添加轉換器,則只有RequestBody可用。(轉換器的添加在后面介紹)
函數也能夠聲明為發送form-encoded和multipart數據。
當函數有@FormUrlEncoded注解的時候,將會發送form-encoded數據,每一個鍵-值對都要被含著名字的@Field注解和提供值的對象所標注
@FormUrlEncoded @POST("/user/edit") CallupdateUser(@Field("first_name") String first, @Field("last_name") String last);
當函數有@Multipart注解的時候,將會發送multipart數據,Parts都使用@Part注解進行聲明
@Multipart @PUT("/user/photo") CallupdateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Multipart parts要使用Retrofit的眾多轉換器之1或實現RequestBody來處理自己的序列化。
可使用@Headers注解給函數設置靜態的header
@Headers("Cache-Control: max-age=640000") @GET("/widget/list") Call widgetList();
@Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" })
@GET("/users/{username}") CallgetUser(@Path("username") String username);
需要注意的是:header不能被相互覆蓋。所有具有相同名字的header將會被包括到要求中。
可使用@Header注解動態的更新1個要求的header。必須給@Header提供相應的參數,如果參數的值為空header將會被疏忽,否則就調用參數值的toString()方法并使用返回結果
@GET("/user") CallgetUser(@Header("Authorization") String authorization)
使用OkHttp攔截器可以指定需要的header給每個Http要求
OkHttpClient client = new OkHttpClient() client.networkInterceptors().add(new Interceptor() {
@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException { com.squareup.okhttp.Response response = chain.proceed(chain.request()) // Do anything with response here
return response }
}) Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL)
... .client(client) .build()
同步 VS 異步
每個Call實例可以同步(call.excute())或異步(call.enquene(CallBack callBack))的被履行,每個實例僅僅能夠被使用1次,但是可以通過clone()函數創建1個新的可用的實例。
也能夠使用CallBack定義1個異步方法:
@GET("/user/{id}/photo") void getUserPhoto(@Path("id") int id, Callbackcb);
在Android上,回調被履行在主線程;在JVM上,回調被履行在發送Http要求的線程。
Retrofit 配置
Retrofit是通過API接口轉換成的可調用的對象,默許有1些公道的配置,這些配置也能夠進行定制。
轉換器
默許情況下,Retrofit只能夠反序列化Http體為OkHttp的ResponseBody類型,并且只能夠接受ResponseBody類型的參數作為@body。
添加轉換器可以支持其他的類型,為了方便的適應流行的序列化庫,Retrofit提供了6個兄弟模塊:
-
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進行通訊,或想要使用不同的庫實現已存在的格式,你可以很方便的創建自己的轉換器。創建方式:新建1個類繼承Converter.Factory類,并在構建Retrofit實例時傳入轉換器實例。
Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作為回調適配器 .addConverterFactory(GsonConverterFactory.create()) // 使用Gson作為數據轉換器 .build()
使用RxJava和Gson轉換器需要添加依賴
compile com.squareup.retrofit:adapter-rxjava:2.0.0-beta1 compile com.squareup.retrofit:converter-gson:2.0.0-beta1
配合RxJava使用
在Rxjava下,你可以用Observable定義異步函數:
@GET("/user/{id}/photo") ObservablegetUserPhoto(@Path("id") int id);
現在你可以做很多事情,不光可以獲得數據還可以改變數據。
Retrofit 支持Observable致使了將多個REST調用組合在1起變得簡單了。例如,我們有1個調用去獲得照片,第2個調用去獲得原生數據,我們可以將結果1起打包。
Observable.zip(
service.getUserPhoto(id),
service.getPhotoMetadata(id),
(photo, metadata) -> createPhotoWithData(photo, metadata)) .subscribe(photoWithData -> showPhoto(photoWithData))
通過RxJava + Retrofit可讓多個REST調用組合成1個變得更簡單。
RxJava系列教程:
-
深入淺出RxJava(1:基礎篇)
-
深入淺出RxJava(2:操作符)
-
深入淺出RxJava3