Retrofit2
現時点では2.0.0-beta1が最新です。
Callアダプタというものが追加されています。以下のような特徴があるようです。
これ以外にDynamic URL,Dynamic Query Paramも便利そうです。
Simple HTTP with Retrofit 2 (Droidcon NYC 2015) by Jake Wharton
- Call encapsulates single request/response interaction
- Models a single request/response pair
- Separates request creation from response handling
- Each instance can only be used once..
- ...instances can be cloned
- Supports both synchronous and asynchronous execution.
- can be (actually) canceled
GitHubのリポジトリにあるサンプルコードを参考にRxJavaCallアダプタの使い方を試してみました。
サンプルにはObservableを利用する方法が書かれていなかったので、Jake Wharton氏のスライドを参考に修正しました。
Callアダプタで実行
まずはサンプルコードのままで実行してみました。非同期での実行も試してみます。
インタフェースの定義
サンプルではデフォルトのCallでラップされています。
import retrofit.Call;
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
Retrofitを生成
ビルダでRetrofitインスタンスを生成します。
コンバータファクトリはGsonConverterFactoryを追加します。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
同期実行
サンプルでは同期実行しています。
GitHub github = retrofit.create(GitHub.class);
Call<List<Contributor>> call = github.contributors("square", "retrofit");
List<Contributor> contributors = call.execute().body();
for (Contributor contributor : contributors) {
Log.d(TAG, contributor.login + " (" + contributor.contributions + ")");
}
非同期実行
非同期で実行する場合は、enqueueメソッドを利用します。
GitHub github = retrofit.create(GitHub.class);
Call<List<Contributor>> call = github.contributors("square", "retrofit");
call.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(Response<List<Contributor>> response) {
for (Contributor contributor : response.body()) {
Log.d(TAG, contributor.login + " (" + contributor.contributions + ")");
}
}
@Override
public void onFailure(Throwable t) {
}
});
RxJavaで実行
ライブラリ
以下のライブラリを使用しています。adapter-rxjavaが必要です。
dependencies {
compile 'io.reactivex:rxjava:1.0.14'
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
}
アダプタの設定
ビルダでRxJavaCallアダプタファクトリを追加しておきます。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
これがないと実行時に以下のようなエラーが発生します。
Unable to create call adapter for rx.Observable<java.util.List<Contributor>>
インタフェース
CallではなくObservableでラップします。
import rx.Observable;
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Observable<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
実行
flatMapしてから一件づつ表示してみました。
GitHub github = retrofit.create(GitHub.class);
Observable<List<Contributor>> observable = github.contributors("square", "retrofit");
observable
.flatMap(contributors -> {
return Observable.from(contributors);
})
.subscribe(contributor -> {
Log.d(TAG, contributor.login + " (" + contributor.contributions + ")");
});