retrofit 2.0使用詳解

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種內置的註解:GETPOSTPUTDELETEHEAD,在註解中指定的資源的相對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-encodedmultipart數據。 
當函數有@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調用組合成一個變得更簡單。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章