Retrofit 是Square開發的網絡服務庫
可以 將基於Http協議的API返回的返回的數據轉化爲Java對象方便操作來方便我們操作
public interface NetService {
@GET("server/{param}/api") //以Get 的方式 請求 url(server/{param}/api) >>>>注意這裏的url一般來說並不是完整的url,而是全部url的後面一部分 ,一般來說還有一個BASE_URL>稍後介紹
//其中 以 { } 包圍的部分是一個不定參數 >>由下面 以@Path標註的 以("")包圍的參數指定
//注意,這兩個的名稱要一致 {param} ->("param")
//這是個方法 返回值是一個Call裏面包含是一個List集合,集合裏面裝的是Person數據
//我們很容易猜出Call是 Retrofit在做請求/響應處理的一個封裝
Call<List<Person>> getPerson(@Path("param") String name);
}
我們在這裏簡單提一下 Call的概念,雖然簡單,但是Call是一個很重要的概念.
通過調用Retrofit2的execute(同步)或者enqueue(異步)方法,
發送請求到網絡服務器,並返回一個響應(Response)。
到這裏我們的接口已經定義好了>>我們來看如何使用這個接口
//去創建一個Retrofit 實例 由Retrofit實例來生成一個我們的接口實例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.tp.com/") //很明顯這裏指定了base_url
.build();
//創建一個我們的接口實例
NetService service = retrofit.create(NetService .class);
//有了實例之後我麼就可以直接調用我們定義的方法 來獲取數據 並返回我們的所需
Call<List<Person>> personsCall = service.getPerson("mike");
我們再去調用相應的方法 去執行 同步或者是異步
personsCall .enqueue(new Callback<List<Person>>() { //異步請求 有一個回調接口
@Override
public void onResponse(Response<List<Person>> response, Retrofit retrofit) {
List<Person> userList = response.body(); //這就是我們要的數據
}
@Override
public void onFailure(Throwable t) {
}
});
/************************************************************/
try {
Response<List<Person>> response = personsCall .execute(); //同步請求 直接返回相應數據
List<Person> pers= response.body();
} catch (IOException e) {
e.printStackTrace();
}
Retrofit主要是採用註解的方式來描述我們的Http請求:
1.支持請求的url的地址中的不定參數指定以及查詢參數的指定(這一點我們稍後說)
2.支持將對象轉換成請求體(JSON,protocol buffers等等)
protocol buffers是Google公司開發的一種數據描述語言,類似於XML能夠將結構化數據序列化,可用於數據存儲、通信協議等方面。現階段支持C++、JAVA、Python等三種編程語言。不必深究就是和JSON類似的一種東西
3.支持Multipart的請求體以及文件上傳、
在定義一個請求接口的時候,方法上的註解和參數表明我們去怎樣去執行這個請求
//每一個接口都必須使用HTTP註解,我們在註解中指明**請求方式和訪問的相對地址**
// 目前支持的請求方式有五種 GET, POST, PUT, DELETE, HEAD
@GET("server/list") //請求方式 get,請求的相對地址 server/list
//當然我們也可以在我們的相對地址上攜帶請求參數,
@GET("server/list?id=1213")
請求地址url的操作
//前面我就提到了註解上寫的請求的相對地址中放置的參數我麼是可以去動態指定
//還有一點 我們也可以指定查詢參數 >>查詢參數是什麼呢?我解釋一下
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
請求參數:
請求體頭部信息設置
在我們定義一個請求方式之前我們也可以鏡頭的設置我們請求體的頭部信息
@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註解動態去改變的
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
//注意 @Header註解中指定的參數名稱必須正確,
//如果沒有傳入數據(authorization==null),那麼頭部就會被省略掉,否則就會調用參數(authorization)的toString方法轉成String類型,設置到對應參數("Authorization")上
//如果所有的請求都需要指定一個頭部信息,我們可以通過OkHttp interceptor.去指定
同步和異步
每一個接口實例都都可以異步或者同步的執行,每一個實例只能使用一次,但是我們可以通過克隆(調用 clone())創建一個新的實例,也可以使用
在Android中,請求的回調接口會在Android主線程中執行
在普通的Java程序中,回調和執行Http請求的線程是統一線程
Retrofit默認的設置已經比較健全的向我們提供一些列可以使用的方法,但是我們也可以自定義,這裏我們不做敘述。
數據轉換
默認情況下,Retrofit只能將Http的信息體轉換成OKHttp的響應體ResponseBody的類型,也只支持OkHttp類型的請求體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
我們來懶一下比較常用的JSON類型的數據
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
//這一句就可以讓數據支持JSON類型
.build();
我們可以自定義轉換類型 只需要我們去繼承自 Converter.Factory類 定製我們自己的轉換方法即可
以上我們只瞭解了Retrofit的大概原理,在實際應用中沒什麼用 ,
我們接下來看一個實際的例子,上代碼
使用OKHttp+Retrofit
//jar包支持
dependencies {
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.okhttp:okhttp:2.4.0'
}
創建我們所需要的JavaBean(數據對應的實體類)
public class User implements Serializable {
private String name;
private String pass;
//省略get set方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", pass='" + pass + '\'' +
'}';
}
}
創建我們所需要的請求接口
public interface UserService {
@GET("userAction/{name}") //url由方法中的傳入參數動態的指定
Call<List<User>> getUser(@Path("name") String name);
}
//創建一個Retrofit實例 進行各種配置
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")//地址前綴
.addConverterFactory(GsonConverterFactory.create()) //設置數據轉換
.client(new OkHttpClient()) //設置客戶端類型
.build();
//由Retrofit實例得到我們請求接口的實例
UserService userService = retrofit.create(UserService.class);
//同步或者異步的去獲取數據
//這是異步獲取獲取 攜帶一個回調接口
call.enqueue(new Callback<List<User>>() {
@Override
public void onResponse(Response<List<User>> response, Retrofit retrofit) {
List<User> userList = response.body(); //這就是我們要的數據
}
@Override
public void onFailure(Throwable t) {
}
});
//這是同步獲取參數 直接返回響應的信息
try {
Response<List<User>> response = call.execute();
List<User> users = response.body();
} catch (IOException e) {
e.printStackTrace();
}