原文鏈接:Tips on updating to Retrofit 2
ps:其實(shí)我老早就更新到Retrofit2了 但是不同的beta版目前改變還是挺大的弃甥,如果你在用的話 嚼吞,要時(shí)刻跟進(jìn)并查看它的changelog.該文章還是比較傾向于1.9升級2.0 但是就像前面說的 beta2到beta4改變也是非常大的 所以同樣可以參考用于備忘
Retrofit2.0已經(jīng)公開發(fā)布幾個(gè)月了,但是現(xiàn)在依然是beta版安寺,一些開發(fā)者已經(jīng)開始從之前的版本進(jìn)行升級,雖然官方已經(jīng)提供了文檔,文章或博客讓你了解最新版的相關(guān)信息增显,但是在StackOverflow還是可以看到一些提問關(guān)于在升級版本的過程中怎么處理常見功能像logging打印日志,添加request parameter或者使用JSON對象等脐帝,所以在這篇文章中同云,我會告訴你關(guān)于這些問題的一些技巧。
寫文章時(shí)堵腹,Retrofit的版本是v2.0.0-beta4.
新的group id
第一個(gè)你會注意到的改變是新的group id,變成了com.squareup.retrofit2炸站,所以新的依賴聲明是:
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
新的包名
主包名已經(jīng)改成了
package retrofit2;
這意味的你需要更改所有關(guān)于Retrofit的import,此外疚顷,如果你還有其他涉及到包名的代碼或任務(wù)旱易,記得也要更新他們。
proguard 配置
因?yàn)樾掳鹊蹋绻汩_啟了混淆代碼咒唆,第一件要做的事就是更新配置文件的規(guī)則,它們可以在官方網(wǎng)站找到:
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
okhttp
okhttp現(xiàn)在Retrofit2內(nèi)置的默認(rèn)依賴释液,實(shí)際上全释,查看Retrofit2的pom文件(maven的依賴配置文件),會發(fā)現(xiàn)下面的依賴:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
如果你不需要用一個(gè)特殊版本的okhttp或者其他http client,你不用做任何事情误债。
生成服務(wù)接口實(shí)現(xiàn)
service interface implementation generation
你會立即注意到的另外一件事是你的生成服務(wù)接口實(shí)現(xiàn)的代碼沒法編譯了浸船。
下面是Retrofit的典型代碼:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.build();
GitHubService service = restAdapter.create(GitHubService.class);
在Retrofit2,會變成:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.build();
GitHubService service = retrofit.create(GitHubService.class);
你可以看到寝蹈,依然是build模式李命,但是涉及的方法和類已經(jīng)變了。
logging
在開發(fā)中打印網(wǎng)絡(luò)請求和返回結(jié)果是非常重要的箫老,如果你在Retrofit中啟用了這個(gè)功能封字,你會發(fā)現(xiàn)實(shí)現(xiàn)該功能的方法已經(jīng)不可用了。
setLogLevel(RestAdapter.LogLevel.FULL)
那是因?yàn)槟悻F(xiàn)在必須依靠okhttp提供的日志系統(tǒng)耍鬓,HttpLoggingInterceptor.
首先聲明一個(gè)新的依賴阔籽,因?yàn)樗皇莖khttp的一部分所以要另外添加依賴:
compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
然后,創(chuàng)建一個(gè)interceptor實(shí)例:
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
再然后牲蜀,添加到OkHttp client實(shí)例中:
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build();
最后笆制,把client設(shè)置到service interface實(shí)現(xiàn)中:
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(MovieDbApi.END_POINT)
.build();
movieDbApi = retrofit.create(MovieDbApi.class);
ps:其實(shí)這個(gè)log并不是很好用,最好自己參考源碼自己自定義一個(gè)涣达,分分鐘就搞定了在辆。
gson converter
By default, Retrofit can only deserialize HTTP bodies into OkHttp’s ResponseBody type and it can only accept its RequestBodytype for @Body.
這意味得用來支持其他types的converter必須在創(chuàng)建服務(wù)接口時(shí)進(jìn)行設(shè)置
為了讓JSON和Java對象相互轉(zhuǎn)換证薇,我們需要設(shè)置一個(gè)GSON轉(zhuǎn)換器
首先,需要一個(gè)新的依賴:
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
然后設(shè)置converter factory:
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(MovieDbApi.END_POINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
movieDbApi = retrofit.create(MovieDbApi.class);
完整的可用converters可以查看官方文檔
interceptor
Retrofit另外一個(gè)有用的功能是可以攔截http請求進(jìn)行監(jiān)控匆篓,重寫或重試
一個(gè)典型應(yīng)用場景是所有http請求需要加上api key,在Retrofit2之前浑度,可以通過RequestInterceptor實(shí)現(xiàn):
final RequestInterceptor authorizationInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestInterceptor.RequestFacade request) {
request.addQueryParam(MovieDbApi.PARAM_API_KEY, "YOUR_API_KEY");
}
};
然后
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(MovieDbApi.END_POINT)
.setRequestInterceptor(authorizationInterceptor)
.build();
movieDbApi = restAdapter.create(MovieDbApi.class);
在Retrofit2中已經(jīng)不再有效了,因?yàn)槟悻F(xiàn)在必須依靠OKHttp interceptors.
你可以直接在OKHttp client實(shí)例化時(shí)進(jìn)行設(shè)置:
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl url = request.url().newBuilder().addQueryParameter(
MovieDbApi.PARAM_API_KEY, BuildConfig.MOVIE_DB_API_KEY).build();
request = request.newBuilder().url(url).build();
return chain.proceed(request);
}
}).build();
然后像前面那樣設(shè)置client:
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(MovieDbApi.END_POINT)
.build();
movieDbApi = retrofit.create(MovieDbApi.class);
RxJava observable
如果你正在使用RxJava,你會注意到Retrofit2 interfaces已經(jīng)不支持Observable了,實(shí)際上鸦概,Call模式被用于標(biāo)準(zhǔn)的http請求俺泣。
當(dāng)然你可以用你自己的類型,提供你自己的CallAdapter實(shí)現(xiàn)完残,但是幸運(yùn)的是已經(jīng)有可用的了伏钠,RxJavaCallAdapterFactory.簡單說,它把Call轉(zhuǎn)換成Observable.
首先谨设,添加依賴:
com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4
然后熟掂,用addCallAdapterFactory進(jìn)行設(shè)置:
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(MovieDbApi.END_POINT)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
movieDbApi = retrofit.create(MovieDbApi.class);