1. 程式人生 > >Retrofit2.0 從基礎到實戰(一)Retrofit的使用方法

Retrofit2.0 從基礎到實戰(一)Retrofit的使用方法

前言

Retrofit2.0的基礎就是okhttp,現在多與RxJava一起使用,恩,下面先講一下它的優缺點:

優點:

  1. 可以配置不同HTTP client來實現網路請求,如okhttp、httpclient等。
  2. 支援同步、非同步和RxJava
  3. 超級解耦
  4. 可以配置不同的反序列化工具來解析資料,如json、xml等
  5. 使用非常方便靈活
  6. 框架使用了很多設計模式(感興趣的可以看看原始碼學習學習)

缺點:

  1. 不能接觸序列化實體和響應資料
  2. 執行的機制太嚴格
  3. 使用轉換器比較低效
  4. 只能支援簡單自定義引數型別

正文

首先需要匯入工程

compile 'com.squareup.retrofit2:retrofit:2.2.0'

使用方法

1. 介紹

Retrofit可以將你的HTTP API轉化為JAVA的介面的形式。例如:

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

而Retrofit類能夠生成對應介面的實現。例如:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/"
) .build();

GitHubService service = retrofit.create(GitHubService.class);
每一個由介面返回的Call物件都可以與遠端web服務端進行同步或者非同步的HTTP請求通訊。例如:

Call<List<Repo>> repos = service.listRepos("octocat");

Retrofit使用註解來描述HTTP請求:

  1. URL引數的替換和query引數的支援
  2. 物件轉化為請求體(如:JSON,protocol buffers等)
  3. 多重請求體和檔案上傳

2.API說明

Retrofit需要註解介面的請求方法和方法的引數來表明該請求需要怎麼樣的處理。

2.1請求方法

每一個方法必須要有一個HTTP註解來標明請求的方式和相對URL。有五種內建的註解方式:GET、POST、PUT、DELETE以及HEAD。資源的相對URL需要在註解裡面明確給出:

  @GET("users/list")

當然你也可以將query引數直接寫在URL裡:

  @GET("users/list?sort=desc")

2.2 URL操作

一個請求的URL可以通過替換塊和請求方法的引數來進行動態的更新。替換塊是由被{}包裹起來的數字或字母組成的字串構成的,相應的方法引數需要由@Path來註解同樣的字串。例如:

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

Query引數也能同時新增。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

複雜的query引數可以用Map來構建

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

2.3請求主體

能夠通過@Body註解來指定一個方法作為HTTP請求主體

@POST("users/new")
Call<User> createUser(@Body User user);

這個引數物件會被Retrofit例項中的converter進行轉化。如果沒有給Retrofit例項新增任何converter的話則只有RequestBody可以作為引數使用。

2.4 form encode 和 multipart

方法也可以通過宣告來發送form-encoded和multipart型別的資料。
可以通過@FormUrlEncoded註解方法來發送form-encoded的資料。每個鍵值對需要用@Filed來註解鍵名,隨後的物件需要提供值。

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

也可以通過@Multipart註解方法來發送Mutipart請求。每個部分需要使用@Part來註解。

@Multipart@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

多個請求部分需要使用Retrofit的converter或者是自己實現 RequestBody來處理自己內部的資料序列化。

2.5頭部操作

你可以通過使用@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);

注意的是頭部引數並不會相互覆蓋,同一個名稱的所有頭引數都會被包含進請求裡面。
當然你可以通過 @Header 註解來動態更新請求頭。一個相應的引數必須提供給 @Header 註解。如果這個值是空(null)的話,那麼這個頭部引數就會被忽略。否則的話, 值的 toString 方法將會被呼叫,並且使用呼叫結果。

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

當然你可以通過OkHttp interceptor來指定每一個需要的頭部引數。

2.6同步 VS 非同步

你可以同步或者非同步地來執行例項。每個示例只能使用一次,但是可以使用 clone() 來建立一個可以使用的新的例項。
在Android環境中,callback將會在主執行緒中執行;而在JVM環境中,callback將會在和Http請求的同一個執行緒中執行。

3. Retrofit配置

Retrofit類會通過你定義的API介面轉化為可呼叫的物件。預設情況下,Retrofit會返還給你合理的預設值,但也允許你進行指定。

3.1轉化器(Converters)

預設情況下,Retrofit只能將HTTP體反序列化為OKHttp的 ResonseBody 型別,而且只能接收 RequestBody型別作為 @Body。
轉化器的加入可以用於支援其他的型別。以下六個同級模組採用了常用的序列化庫來為你提供方便。

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

下面提供一個使用GsonConverterFactory類生成 GitHubService的介面實現gson反序列化的例子。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);

3.2自定義轉化器

如果你需要與沒有使用Retrofit提供的內容格式的API進行互動的話或者是你希望使用一個不同的庫來實現現有的格式,你也可以輕鬆建立使用自己的轉化器。你需要建立一個繼承自Converter.Factory的類並且在構建介面卡的時候加入到例項裡面。

  1. 下載

原始碼、例子和網站在 available on GitHub

4.1 maven

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.0.0</version>
</dependency>

4.2 gradle

  compile 'com.squareup.retrofit2:retrofit:2.0.0'

Retrofit支援最低 Java7 和 Android 2.3

4.3 混淆

如果你的工程中使用了程式碼混淆,那麼你的配置中需要新增一下的幾行

-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

當然這只是最基本的使用,下面就要將它進行封裝,並整合到程式碼中,與RxJava一起使用