前言
之前做的項目都是用okhttp框架來進行網絡請求的综膀,然后自己自行封裝呻征,雖然以前也有使用過Retrofit谆级,但是Retrofit本質上還是對okhttp的封裝洞拨,而且面試的時候也會經常的Retrofit框架的使用和原理以及它內部使用的設計模式之類的扯罐,這篇文章主要講述如何使用Retrofit請求框架,以及一些使用的細節(jié)烦衣,畢竟是一個很靈活的使用框架歹河,后續(xù)在寫一篇關于Retrofit的源碼解析和使用了哪些設計模式。
Retrofit的導入
我們主要以是2.0版本來進行講解花吟,第一個是Retrofit秸歧,第二個是Retrofit的Json解析,至于有什么用后面就知道了示辈,當然換成別的Json解析也是可以的
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
還有網絡權限也要記得添加:
<uses-permission android:name="android.permission.INTERNET" />
Call接口
首先它需要一個請求的Call接口來進行請求寥茫,Retrofit使用注解的方式來區(qū)分是Get請求還是Post請求等等之類的遣蚀,比如:
public interface ApiService {
@GET(".")
Call<ResponseBody> get();
}
這就是一個很簡單的get請求的接口矾麻,泛型是你要返回的Model數(shù)據(jù)的類型,當然如果你的請求地址是動態(tài)的話芭梯,可以這么寫:
@GET("api/{path}")
Call<ResponseBody> get(@Path("path")int path);
Post請求的話可以這么寫:
@FormUrlEncoded
@POST(".")
Call<ResponseBody> post(@Field("ip") String first);
@FormUrlEncoded
表示這是一個表單的請求险耀,傳輸數(shù)據(jù)類型為鍵值對,使用@Field注解來標示所對應的String類型數(shù)據(jù)的鍵玖喘,從而組成一組鍵值對進行傳遞甩牺。
當然還有其它的注解:
這里需要注意的是在
@GET
或者@POST
的括號里面如果沒有要請求的URL的話贬派,是不能空著的,空的話默認寫 . 或者 / 都是可以的澎媒,如果是空的話則會報錯:創(chuàng)建Retrfit客戶端對象
//創(chuàng)建Retrfit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://wanandroid.com/wxarticle/chapters/json/")
.addConverterFactory(GsonConverterFactory.create())
.build();
通過Retrofit的Builder()
構建者模式可以快速構建客戶端以及所需要的配置搞乏,addConverterFactory()
這個方法就是配置你要用哪個Gson對返回的數(shù)據(jù)進行解析。沒錯戒努,這也是為什么要在Call設置泛型的原因请敦,Retrofit是會自動進行Json解析的,然后最后返回的結果就是解析后的Response實體储玫,這樣就不用另外寫解析Json的業(yè)務邏輯侍筛,大大節(jié)省了代碼的行數(shù)。
這里有一個非常需要注意的點撒穷!這里填入的baseUrl()
是公共的Url匣椰,后面就是跟著你自己定義接口路徑的Url,這里的baseUrl()
填的Url結尾一定要跟一個 / ,否則它也是會報錯的(PS:這里用的請求接口是“玩Android 開放API”的公共API)端礼。
Retrofit的異步請求
//用Retrofit創(chuàng)建接口實例對象
ApiService apiService = retrofit.create(ApiService.class);
//獲取Call對象
Call<DataModel> call = apiService.get();
//開始異步操作
call.enqueue(new Callback<DataModel>() {
@Override
public void onResponse(Call<DataModel> call, Response<DataModel> response) {
Toast.makeText(MainActivity.this, response.body().getData().get(0).getName(), Toast.LENGTH_SHORT).show();
b1.setText("請求完畢更新UI");
}
@Override
public void onFailure(Call<DataModel> call, Throwable t) {
}
});
接下來就跟okhttp的請求差不多禽笑,通過Retrofit客戶端創(chuàng)建一個接口的實例對象弛车,然后通過Call進行獲取,最后使用enqueue()
來進行異步請求返回一個Callback的回調接口蒲每,回調接口的泛型就是Retrofit客戶端Json解析后的Model纷跛。
這里我們發(fā)現(xiàn)了,我們是可以在回調回來的接口里面進行直接更新UI的操作的邀杏,這也就代表回調回來的接口是在主線程上面的贫奠,不像okhttp那樣回調回來的接口還是在子線程上,我們還需要通過Handler來進行更新UI的操作望蜡。
返回原始Json字段
剛剛也說了唤崭,Retrofit返回過來的是已經經過Json解析過的Response對象,但是有時候Json字段是不斷更新的話脖律,你的Model也要進行相應的更新谢肾,這就需要返回原始的字段了,Retrofit本身沒提供這個方法小泉,但是畢竟是封裝okhttp芦疏,它是可以返回原始的Json字段的。
@GET(".")
Call<ResponseBody> get();
//創(chuàng)建Retrfit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://wanandroid.com/wxarticle/chapters/json/")
.addConverterFactory(GsonConverterFactory.create())
.build();
//用Retrofit創(chuàng)建接口實例對象
ApiService apiService = retrofit.create(ApiService.class);
//獲取Call對象
Call<ResponseBody> call = apiService.get();
//開始異步操作
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String json = null;
try {
json = response.body().string();
}catch (Exception e){
e.printStackTrace();
}
Toast.makeText(MainActivity.this, json, Toast.LENGTH_SHORT).show();
b1.setText("請求完畢更新UI");
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
其實只要把Call要傳入的泛型接口改成ResponseBody就好了微姊,對應的回調接口也要改成ResponseBody酸茴,ResponseBody是okhttp的Response的返回體,所以就可以通過string()
方法返回就好了兢交。