實際開發(fā)過程中一般都會選擇一些網(wǎng)絡(luò)框架提升開發(fā)效率。隨著Google對HttpClient 摒棄和Volley框架的逐漸沒落经备,OkHttp開始異軍突起窘俺,而Retrofit則對OkHttp進行了強制依賴病梢,可以簡單理解Retroifit在OKHttp基礎(chǔ)上進一步完善箕般。
Retrofit是由Square公司出品的針對于Android和Java的類型安全的Http客戶端甸昏,目前推出了2.0+的版本顽分。
Retrofit框架項目地址:https://github.com/square/retrofit。
Retrofit官方文檔地址: http://square.github.io/retrofit/
使用Retrofit
接下來我們來學(xué)習(xí)下如何使用Retrofit施蜜。
首先需要在app/build.gradle添加依賴卒蘸。
dependencies {
//...
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
//如果用到gson解析 需要添加下面的依賴
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
}
我們以查號碼歸屬地接口為例 https://www.juhe.cn/docs/api/id/11
Retrofit不能直接使用,需要進行初始化花墩,在這里創(chuàng)建NetWork.java
public class NetWork {
private static Retrofit retrofit;
/**返回Retrofit*/
public static Retrofit getRetrofit(){
if(retrofit==null){
Retrofit.Builder builder = new Retrofit.Builder();//創(chuàng)建Retrfit構(gòu)建器
retrofit = builder.baseUrl("http://apis.juhe.cn/") //指定網(wǎng)絡(luò)請求的baseUrl
.addConverterFactory(GsonConverterFactory.create())//返回的數(shù)據(jù)通過Gson解析
.build();
}
return retrofit;
}
}
Retrofit需要之地baseUrl悬秉,往往一個項目中有很多接口,接口都使用相同的服務(wù)器地址冰蘑,這時候可以把接口地址相同的部分抽取到baseUrl中和泌,Retrofit擴展性極好,可以指定返回的數(shù)據(jù)通過Gson解析祠肥,前提你需要保證項目中有Gson框架和com.squareup.retrofit2:converter-gson:2.1.0的依賴武氓。
除了通過Gson解析還可以使用其它的方式解析,需要的依賴也不同仇箱,有如下幾種:
- 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需要把Http的請求接口封裝到一個接口文件中县恕。
public interface NetInterface {
//獲取號碼歸屬地,返回來類型是Bean, 需要兩個參數(shù)分別為phone何key
@GET("mobile/get")
Call<Bean> getAddress(@Query("phone") String phone, @Query("key") String key);
}
其中Bean是根據(jù)請求的結(jié)果創(chuàng)建的對象.
方法前添加@GET注解表示當(dāng)前請求是Get方式請求剂桥,鏈接的地址是baseUrl+"mobile/get"忠烛,baseUrl在初始化Retrofit的時候指定了,拼到一起就是 http://apis.juhe.cn/mobile/get权逗。
對于 Retrofit 2.0中新的URL定義方式美尸,這里是我的建議:
- baseUrl: 總是以 /結(jié)尾
- url: 不要以 / 開頭
因為如果不是這種方式,拼裝后的結(jié)果和你期望的是不一樣的斟薇,詳情參考官方文檔师坎。
除了Get請求還有下面幾種請求方式
- @POST 表明這是post請求
- @PUT 表明這是put請求
- @DELETE 表明這是delete請求
- @PATCH 表明這是一個patch請求,該請求是對put請求的補充堪滨,用于更新局部資源
- @HEAD 表明這是一個head請求
- @OPTIONS 表明這是一個option請求
- @HTTP 通用注解,可以替換以上所有的注解胯陋,其擁有三個屬性:method,path袱箱,hasBody
最后的HTTP通用注解寫法比較特殊遏乔,請求可以代替之前的請求。下面的寫法和之前的@GET效果是一樣的发笔。
/**
* method 表示請的方法按灶,不區(qū)分大小寫
* path表示路徑
* hasBody表示是否有請求體
*/
@HTTP(method = "GET",path = "mobile/get",hasBody = false)
Call<Bean> getAddress(@Query("phone") String phone, @Query("key") String key);
@Quert表示查詢參數(shù),用于GET查詢筐咧,注解里的字符串是參數(shù)的key值鸯旁,參數(shù)會自動拼裝到Url后面噪矛。
除了上面的注解,再給大家介紹幾種不同的注解铺罢。
常用的注解
@Url:使用全路徑復(fù)寫baseUrl艇挨,適用于非統(tǒng)一baseUrl的場景。示例代碼:
@GET Call<ResponseBody> XXX(@Url String url);
@Streaming:用于下載大文件韭赘。示例代碼:
@Streaming @GET Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
//獲取數(shù)據(jù)的代碼
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();
@Path:URL占位符缩滨,用于替換和動態(tài)更新,相應(yīng)的參數(shù)必須使用相同的字符串被@Path進行注釋
//實際請求地址會給句groupId的值發(fā)生變化--> http://baseurl/group/groupId/users
@GET("group/{id}/users") Call<List<User>> groupList(@Path("id") int groupId);
@QueryMap:查詢參數(shù),和@Query類似泉瞻,區(qū)別就是后面需要Map集合參數(shù)脉漏。示例代碼:
Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options);
@Body:用于POST請求體,將實例對象根據(jù)轉(zhuǎn)換方式轉(zhuǎn)換為對應(yīng)的json字符串參數(shù)袖牙,這個轉(zhuǎn)化方式是GsonConverterFactory定義的侧巨。 示例代碼:
@POST("add")
Call<List<User>> addUser(@Body User user);
@Field,@FieldMap:Post方式傳遞簡單的鍵值對鞭达,需要添加@FormUrlEncoded表示表單提交
@FormUrlEncoded @POST("user/edit") Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Part司忱,@PartMap:用于POST文件上傳,其中@Part MultipartBody.Part代表文件畴蹭,@Part(“key”) RequestBody代表參數(shù)坦仍,需要添加@Multipart表示支持文件上傳的表單。
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") RequestBody description,
@Part MultipartBody.Part file);
完成請求實例
了解了Retrofit叨襟,我們用Retrofit請求完成請求繁扎,Retrofit使用起來比較省事,核心代碼如下所示:
//初始化Retrofit,加載接口
NetInterface netInterface = NetWork.getRetrofit().create(NetInterface.class);
//請求接口
netInterface.getAddress(editText.getText().toString(),"你的app key")
.enqueue(new Callback<Bean>() {
@Override
public void onResponse(Call<Bean> call, Response<Bean> response) {
//請求成功
Bean bean = response.body();
//...
}
@Override
public void onFailure(Call<Bean> call, Throwable t) {
//請求失敗
}
});
Retrofit會自動在子線程中進行網(wǎng)絡(luò)請求糊闽,請求結(jié)束切換到主線程中梳玫,而且內(nèi)部使用了線程池,對網(wǎng)絡(luò)請求的緩存控制的也非常到位墓怀,網(wǎng)絡(luò)響應(yīng)速度也是很快的汽纠,使用起來非常的爽!
RxJava和Retrofit結(jié)合
RxJava非常強大卫键,就連Retrofit都要抱下他的大腿傀履,Retrofit也可以用RxJava方式進行網(wǎng)絡(luò)請求,只需要對上面的代碼進行改造即可莉炉。
首先添加框架依賴钓账。
dependencies {
//...
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.6'
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
//如果用到gson解析 需要添加下面的依賴
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
//Retrofit使用RxJava需要的依賴
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
}
修改Retrofit初始化的代碼:
public class NetWork {
private static Retrofit retrofit;
/**返回Retrofit*/
public static Retrofit getRetrofit(){
if(retrofit==null){
//創(chuàng)建Retrfit構(gòu)建器
Retrofit.Builder builder = new Retrofit.Builder();
//指定網(wǎng)絡(luò)請求的baseUrl
retrofit = builder.baseUrl("http://apis.juhe.cn/")
//返回的數(shù)據(jù)通過Gson解析
.addConverterFactory(GsonConverterFactory.create())
//使用RxJava模式
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
return retrofit;
}
}
上面代碼我們通過,添加代碼addCallAdapterFactory(RxJavaCallAdapterFactory.create())
就變成了使用RxJava模式絮宁。
接口也需要修改,把方法的返回值類型由Call改成了RxJava中的Observable梆暮。
public interface NetInterface {
//獲取號碼歸屬地,返回來類型是Bean, 需要兩個參數(shù)分別為phone何key
@GET("mobile/get")
Observable<Bean> getAddress(@Query("phone") String phone, @Query("key") String key);
}
接下來修改最終網(wǎng)絡(luò)請求的代碼绍昂,可以改成RxJava方式了啦粹。
NetInterface netInterface = NetWork.getRetrofit().create(NetInterface.class);
//RxJava方式
netInterface.getAddress(editText.getText().toString(),"你的app key")
.subscribeOn(Schedulers.io())//設(shè)置網(wǎng)絡(luò)請求在子線程中
.observeOn(AndroidSchedulers.mainThread())// 回調(diào)在主線程中
.subscribe(new Action1<Bean>() {
@Override
public void call(Bean bean) {
//請求成功
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
//請求失敗
}
});
總結(jié)
這是Retrofit基礎(chǔ)篇偿荷, 后面有時間再繼續(xù)深入研究