Retrofit2 目前最優雅的網絡請求框架
身為Geek的我們,面對不斷更新換代的技術是不是有點感到迷茫呢?其實只要掌握正確的學習方法,新的技術也就不畏懼了。
正是面哥的鞭策,我決定開始看英文的技術文檔,學習新技術也是直接看官網的技術文檔,本篇文章就是我在Retrofit2的官網看完英文文檔 Retrofit 以及參考多篇博文之后總結出來的。
Retrofit
Retrofit
是一個Square開發的類型安全的REST 安卓 客戶端請求庫。這個庫為網絡認證、API請求以及用OkHttp發送網絡請求提供了強大的框架 。
Retrofit 把REST API返回的數據轉化為 Java 對象,就像ORM框架那樣,把 數據庫 內的存儲的數據轉化為相應的Java
bean對象。 那么我們知道Retrofit是一個類型安全的網絡框架,而且它是使用REST API的.
REST :
Resources Representational State Transfer
資源表現層狀態轉化 每一個URI代表一種資源
客戶端和服務器之間,傳遞這種資源的某種 表現層(“資源”具體呈現出來的形式,比如.txt,.png,.jpg)
客戶端通過四個HTTP動詞(GET用來獲取資源,POST用來新建或更新資源,PUT用來更新資源,DELETE用來刪除資源)對服務器端資源進行操作,實現”表現層狀態轉化”
Retrofit的簡單使用
這里使用官方的例子介紹,也是以github的api做 測試
第零步:
添加依賴:
//okHttp
compile 'com.squareup.okhttp3:okhttp:3.2.0'
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
準備api接口:
https://api.github.com/users/wu-leaf/repos
需要封裝的javabean 類
其中我抽取出用來測試的屬性如下4個:
public class Repo {
private int id;
private String name;
private String full_name;
private String fork;
//get\set方法
第一步:
改造你的HTTP API變成一個Java接口。
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
第二步:
Retrofit 生成一個GitHubService 接口的實現
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
來自創建的GitHubService的每個調用都可以向遠程Web服務器發出同步或異步HTTP請求。
Call<List<Repo>> repos = service.listRepos("wu-leaf");
第三步:
異步調用
repos.enqueue(new Callback<List<Repo>>() {
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
Log.d("TAG",response.body().toString());
response_tv.setText(response.body().toString());
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
if (call.isCanceled()){
Log.d("TAG",t.toString());
}else{
Log.e("TAG",t.toString());
}
}
});
同步調用:
當然不能在主線程調用
Call<Repo> clone = repos.clone();
Response<Repo> response = clone.execute();
Repobody = response.body();
這個例子是不是挺簡單的,現在現在正式了解下常用api吧
常用API介紹
接口方法及其參數的注釋指示如何處理請求。
請求方法
每個方法必須具有提供請求方法和相對URL的HTTP注釋。 有五個內置注釋:GET,POST,PUT,DELETE和HEAD。 資源的相對URL在注釋中指定。
@GET("users/list")
您還可以在URL中指定查詢參數。
@GET("users/list?sort=desc")
URL 相關操作
可以使用替換塊(占位符)和方法上的參數動態更新請求URL。 替換塊是由{and}包圍母數字字符串。 相應的參數必須使用相同的字符串用@Path注釋。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
也可以添加查詢參數。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
對于復雜的查詢參數組合,可以使用Map。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
請求體
可以指定一個對象用作帶有@Body注釋的HTTP請求體。
@POST("users/new")
Call<User> createUser(@Body User user);
該對象也將使用Retrofit實例上指定的轉換器進行轉換。 如果沒有添加轉換器,則只能使用RequestBody。
提交表單和多部分數據
方法也可以聲明為發送提交表單和多部分數據。
當方法上存在@FormUrlEncoded時,將發送表單編碼的數據。 每個鍵值對都使用包含名稱的@Field和提供值的對象進行注釋。
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
多部分請求時使用@Multipart存在的方法。部分使用@Part注釋聲明。
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
多部分使用Retrofit的轉換器,或者它們可以實現RequestBody來處理自己的序列化。
請求頭操作
您可以使用@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攔截器指定。
同步 vs 異步
Call 實例可以同步或異步執行。 每個實例只能使用一次,但調用clone()將創建一個可以使用的新實例。
在 Android 上,回調將在主線程上執行。 在JVM上,回調將發生在執行HTTP請求的同一線程上。
Retrofit 配置
Retrofit是將API接口轉換為可調用對象的類。 默認情況下,Retrofit將為您的平臺提供正常默認值,但它允許自定義。
轉換器:
默認情況下,Retrofit只能將HTTP主體反序列化為OkHttp的ResponseBody類型,并且它只能接受@Body的RequestBody類型。
可以添加轉換器以支持其他類型。 六個同級模塊適應流行的序列化庫為您方便使用。
- 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);
自定義轉換器
如果您需要與使用Retrofit不支持開箱即用的內容格式(例如YAML,txt,自定義格式)的API進行通信,或者希望使用其他庫來實現現有格式,則可以輕松創建 你自己的轉換器。 創建一個擴展Converter.Factory類的類,并在構建適配器時傳遞實例。
依賴方式:
MAVEN
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.2.0</version>
</dependency>
GRADLE
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
Retrofit需要至少 Java 7或Android 2.3。
PROGUARD混淆
如果在項目中使用Proguard,請在配置中添加以下行:
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
來自:http://www.androidchina.net/6550.html