更新到Retrofit2的一些技巧

原文鏈接:Tips on updating to Retrofit 2
簡述地址:更新到Retrofit2的一些技巧

ps:其實我老早就更新到Retrofit2了 但是不同的beta版目前改變還是挺大的,如果你在用的話 ,要時刻跟進並查看它的changelog.該文章還是比較傾向於1.9升級2.0 但是就像前面說的 beta2到beta4改變也是非常大的 所以同樣可以參考用於備忘

Retrofit2.0已經公開發布幾個月了,但是現在依然是beta版,一些開發者已經開始從之前的版本進行升級,雖然官方已經提供了文檔,文章或博客讓你瞭解最新版的相關信息,但是在StackOverflow還是可以看到一些提問關於在升級版本的過程中怎麼處理常見功能像logging打印日誌,添加request parameter或者使用JSON對象等,所以在這篇文章中,我會告訴你關於這些問題的一些技巧。

寫文章時,Retrofit的版本是v2.0.0-beta4.

新的group id

第一個你會注意到的改變是新的group id,變成了com.squareup.retrofit2,所以新的依賴聲明是:

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'

新的包名

主包名已經改成了

package retrofit2;

這意味的你需要更改所有關於Retrofit的import,此外,如果你還有其他涉及到包名的代碼或任務,記得也要更新他們。

proguard 配置

因爲新包名,如果你開啓了混淆代碼,第一件要做的事就是更新配置文件的規則,它們可以在官方網站找到:

-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

okhttp

okhttp現在Retrofit2內置的默認依賴,實際上,查看Retrofit2的pom文件(maven的依賴配置文件),會發現下面的依賴:

<dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
</dependency>

如果你不需要用一個特殊版本的okhttp或者其他http client,你不用做任何事情。

生成服務接口實現

service interface implementation generation

你會立即注意到的另外一件事是你的生成服務接口實現的代碼沒法編譯了。

下面是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模式,但是涉及的方法和類已經變了。

logging

在開發中打印網絡請求和返回結果是非常重要的,如果你在Retrofit中啓用了這個功能,你會發現實現該功能的方法已經不可用了。

setLogLevel(RestAdapter.LogLevel.FULL)    

那是因爲你現在必須依靠okhttp提供的日誌系統,HttpLoggingInterceptor.

首先聲明一個新的依賴,因爲它不是okhttp的一部分所以要另外添加依賴:

compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'

然後,創建一個interceptor實例:

HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

再然後,添加到OkHttp client實例中:

OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build();

最後,把client設置到service interface實現中:

Retrofit retrofit = new Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(MovieDbApi.END_POINT)
    .build();
movieDbApi = retrofit.create(MovieDbApi.class);

ps:其實這個log並不是很好用,最好自己參考源碼自己自定義一個,分分鐘就搞定了。

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必須在創建服務接口時進行設置

爲了讓JSON和Java對象相互轉換,我們需要設置一個GSON轉換器

首先,需要一個新的依賴:

compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

然後設置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另外一個有用的功能是可以攔截http請求進行監控,重寫或重試

一個典型應用場景是所有http請求需要加上api key,在Retrofit2之前,可以通過RequestInterceptor實現:

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中已經不再有效了,因爲你現在必須依靠OKHttp interceptors.

你可以直接在OKHttp client實例化時進行設置:

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();

然後像前面那樣設置client:

Retrofit retrofit = new Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(MovieDbApi.END_POINT)
    .build();
movieDbApi = retrofit.create(MovieDbApi.class);

RxJava observable

如果你正在使用RxJava,你會注意到Retrofit2 interfaces已經不支持Observable了,實際上,Call模式被用於標準的http請求。

當然你可以用你自己的類型,提供你自己的CallAdapter實現,但是幸運的是已經有可用的了,RxJavaCallAdapterFactory.簡單說,它把Call轉換成Observable.

首先,添加依賴:

com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4

然後,用addCallAdapterFactory進行設置:

Retrofit retrofit = new Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(MovieDbApi.END_POINT)
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .build();
movieDbApi = retrofit.create(MovieDbApi.class);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章