Retrofit簡(jiǎn)介:
一款基于異步線程的網(wǎng)絡(luò)請(qǐng)求框架宫仗,一款android安全類型的http客戶端易桃,支持線程安全玛痊,開發(fā)者無需關(guān)注線程問題赴恨,同樣是基于鏈?zhǔn)骄幊趟枷氲? 一款網(wǎng)絡(luò)請(qǐng)求器。底層集成谷歌自身的Okhttp箕憾,它本身不具備http標(biāo)準(zhǔn)網(wǎng)絡(luò)訪問基礎(chǔ)牡借,它需要依okhttp進(jìn)行網(wǎng)絡(luò)訪問,另外從Android4.4開始- HttpURLConnection的底層實(shí)現(xiàn)采用的是okHttp袭异,最重要的時(shí)Retrofit完美支持 Rxjava钠龙,這里關(guān)于Retrofit的好處不做過多介紹。
官方介紹
一扁远、簡(jiǎn)介
Retrofit可將HTTP API轉(zhuǎn)換為Java接口
public interface GitHubService {@GET("users/{user}/repos")Call<List<Repo>> listRepos(@Path("user") String user);}
Retrofit類生成GitHubService接口的實(shí)現(xiàn)俊鱼。
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/").build();GitHubService service = retrofit.create(GitHubService.class);
每個(gè)來自創(chuàng)建GitHub服務(wù)的調(diào)用都可以向遠(yuǎn)程Web服務(wù)器發(fā)出同步或異步HTTP請(qǐng)求。
Call<List<Repo>> repos = service.listRepos("octocat");
使用注解描述HTTP請(qǐng)求:
*URL支持參數(shù)替換和查詢參數(shù)
*對(duì)象轉(zhuǎn)換為請(qǐng)求體(例如畅买,JSON并闲,協(xié)議緩沖區(qū))
*多部分請(qǐng)求體和文件上傳
二、API聲明
通過接口方法及其參數(shù)的注解指導(dǎo)如何處理請(qǐng)求谷羞。
請(qǐng)求方法
每個(gè)方法必須具有提供請(qǐng)求方法和相對(duì)URL的HTTP注解帝火。 有五個(gè)內(nèi)置注解:GET,POST湃缎,PUT犀填,DELETE和HEAD。 資源的相對(duì)URL在注解中指定嗓违。
@GET("users/list")
還可以在URL中指定查詢參數(shù)九巡。
@GET("users/list?sort=desc")
網(wǎng)址操作
可以使用替換塊和方法上的參數(shù)動(dòng)態(tài)更新請(qǐng)求URL。 替換塊是由{和}包圍的字母數(shù)字字符串蹂季。 相應(yīng)的參數(shù)必須使用相同的字符串用@Path注解冕广。
@GET("group/{id}/users")Call<List<User>> groupList(@Path("id") int groupId);
也可以添加查詢參數(shù)。
@GET("group/{id}/users")Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort)
對(duì)于復(fù)雜的查詢參數(shù)組合偿洁,可以使用Map撒汉。
@GET("group/{id}/users")Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
請(qǐng)求主體
可以指定一個(gè)帶有@Body對(duì)象用作注解的HTTP請(qǐng)求主體。
@POST("users/new")Call<User> createUser(@Body User user);
注:該對(duì)象也將使用Retrofit實(shí)例上指定的轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換涕滋。 如果沒有添加轉(zhuǎn)換器睬辐,則只能使用RequestBody。
方法也可以聲明為發(fā)送表單編碼和多部分?jǐn)?shù)據(jù)宾肺。
當(dāng)方法上存在@FormUrlEncoded時(shí)溯饵,將發(fā)送表單編碼的數(shù)據(jù)。 每個(gè)鍵值對(duì)都使用包含名稱的@Field和提供值的對(duì)象進(jìn)行注解锨用。
@FormUrlEncoded@POST("user/edit")Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
當(dāng)方法上存在@Multipart時(shí)瓣喊,將使用多部分請(qǐng)求。 部分是被聲明使用@Part注解黔酥。
@Multipart@PUT("user/photo")Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
多部分使用Retrofit的轉(zhuǎn)換器藻三,或者它們可以實(shí)現(xiàn)RequestBody來處理自己的序列化洪橘。
header操作
可以使用@Headers注解為方法設(shè)置靜態(tài)頭。
@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);
請(qǐng)注意棵帽,頭不會(huì)相互覆蓋熄求。 具有相同名稱的所有頭將包含在請(qǐng)求中。
請(qǐng)求頭可以使用@Header注解動(dòng)態(tài)更新逗概。 必須向@Header提供相應(yīng)的參數(shù)弟晚。 如果值為null,則將省略標(biāo)題逾苫。 否則卿城,toString將使用被調(diào)用的值做為結(jié)果。
@GET("user")Call<User> getUser(@Header("Authorization") String authorization)
頭需要被添加到每個(gè)請(qǐng)求中铅搓,可被當(dāng)做一個(gè)特定的OkHttp攔截器使用
同步 VS 異步
Call實(shí)例可以同步或異步執(zhí)行瑟押。 每個(gè)實(shí)例只能使用一次,但調(diào)用clone()將創(chuàng)建一個(gè)可以使用的新實(shí)例星掰。
在Android上多望,回調(diào)將在主線程上執(zhí)行。 在JVM上氢烘,回調(diào)將發(fā)生在執(zhí)行HTTP請(qǐng)求的同一線程上怀偷。
三、Retrofit配置
Retrofit是將API接口轉(zhuǎn)換為可調(diào)用對(duì)象的類播玖。 默認(rèn)情況下椎工,Retrofit將為您的平臺(tái)提供正常默認(rèn)值,但允許自定義蜀踏。
Converters(轉(zhuǎn)換器)
默認(rèn)情況下晋渺,Retrofit只能將HTTP主體反序列化為OkHttp的ResponseBody類型,并且它只能接受@Body的RequestBody類型
但是添加Converters可以支持其他類型脓斩,六個(gè)同級(jí)模塊適應(yīng)流行的序列化庫,為您提供方便畴栖。
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
下面是一個(gè)使用GsonConverterFactory類來生成GitHubService接口的實(shí)現(xiàn)的示例随静,該接口使用Gson進(jìn)行反序列化。
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com").addConverterFactory(GsonConverterFactory.create()).build();
GitHubService service = retrofit.create(GitHubService.class);
自定義轉(zhuǎn)換器
如果您需要與使用Retrofit不支持模型即用的內(nèi)容格式(例如YAML吗讶,txt燎猛,自定義格式)的API進(jìn)行通信,或者您希望使用其他庫來實(shí)現(xiàn)現(xiàn)有格式照皆,則可以輕松創(chuàng)建 你自己的轉(zhuǎn)換器重绷。 創(chuàng)建一個(gè)擴(kuò)展Converter.Factory類的類,并在構(gòu)建適配器時(shí)傳遞實(shí)例膜毁。
支持Retrofit需要至少Java 7或Android 2.3昭卓。
如果在項(xiàng)目中使用Proguard(混淆)愤钾,請(qǐng)?jiān)谂渲弥刑砑右韵滦校?/p>
# 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
使用聲明:
Retrofit1.X與Retrofot2.X在初始化,網(wǎng)絡(luò)請(qǐng)求候醒、回調(diào)等有較大差異能颁,本文是基于
Retrofit2.X。
1.添加依賴
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
備注:這里Retrofit2的各個(gè)版本號(hào)必須一致
2.創(chuàng)建Retrofit回調(diào)的接口
public interface WeatherApi {
@GET("/microservice/weather?citypinyin=beijing")
Call<WeatherBean> getWeather();
}
備注:@GET里面的是baseUrl的后綴倒淫,用于拼接完整的Url
3.初始化Retrofit實(shí)例
String baseUrl = "http://apistore.baidu.com/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
4.用Retrofit創(chuàng)建接口的代理對(duì)象伙菊,操作接口方法
WeatherApi weatherApi = retrofit.create(WeatherApi.class);
Call<WeatherBean> weatherCall = weatherApi.getWeather();
備注:步驟3中的addConverterFactory(GsonConverterFactory.create())是對(duì)于
Call<T>中T的轉(zhuǎn)換, 默認(rèn)是Call<ResponseBody>轉(zhuǎn)化成你自己的Call<Poju>
5.執(zhí)行回調(diào)獲取數(shù)據(jù)(同步/異步--execute/enqueue)
weatherCall.enqueue(new Callback<WeatherBean>() {
@Override
public void onResponse(Call<WeatherBean> call, Response<WeatherBean> response) {
String weather = response.body().retData.weather;
tv.setText(weather);
}
@Override
public void onFailure(Call<WeatherBean> call, Throwable t) {
}
});
此篇簡(jiǎn)單介紹了Retrofit的簡(jiǎn)介和基本使用敌土,下一篇會(huì)介紹對(duì)其接口中注解的理
解以及配合Okhttp實(shí)現(xiàn)網(wǎng)絡(luò)響應(yīng)信息攔截
代碼托管地址