例として Qiita API v1 を利用して、Qiitaの 新着投稿の一覧 を取得してみます。
必要なライブラリをプロジェクトへ導入
本投稿の執筆時点(2016.11.04)で最新版を導入します。
- 
『Gradle Retrolambda Plugin』は Retrolambda のラムダ式を利用できるようにするものです(RxJava 利用コードが煩雑になるのを回避する為)。また Retrolambda を導入するにあたり、開発環境(OS X を想定)には Java 8 を導入してください(Oracleのサイトはこちら)。 その他、付随して必要になる OkHttp、Gson 等も導入します。 build.gradlebuildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.1' + classpath 'me.tatarka:gradle-retrolambda:3.3.0' } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }app/build.gradleapply plugin: 'com.android.application' + apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 24 buildToolsVersion "24.0.3" defaultConfig { applicationId "io.github.hkusu.rxRetrofit" minSdkVersion 21 targetSdkVersion 23 versionCode 1 versionName "0.0.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' compile "com.android.support:support-v4:24.2.1" compile "com.android.support:support-annotations:24.2.1" + compile 'io.reactivex:rxjava:1.2.1' + compile 'io.reactivex:rxandroid:1.2.1' + compile 'com.squareup.retrofit2:retrofit:2.1.0' + compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' + compile 'com.squareup.retrofit2:converter-gson:2.1.0' + compile 'com.google.code.gson:gson:2.7' + compile 'com.squareup.okhttp3:okhttp:3.4.1' testCompile 'junit:junit:4.12' }
Gson モデルの作成
API のレスポンス(JSON形式)で受け取るデータを Gson のモデルで表現します。全ての項目を定義する必要はなく、受け取りたい項目のみでよいです。
// ...
public class QiitaItem {
    @SerializedName("id")
    public int id;
    @SerializedName("uuid")
    public String uuid;
    @SerializedName("title")
    public String title;
    @SerializedName("url")
    public String url;
    @SerializedName("user")
    public QiitaItemUser user;
}
入れ子の場合(上記でいうとuser)は子のモデルも作成します。
// ...
public class QiitaItemUser {
    @SerializedName("id")
    public int id;
    @SerializedName("url_name")
    public String urlName;
    @SerializedName("profile_image_url")
    public String profileImageUrl;
}
API の作成
Retrofit2 で API を定義します。
// ...
public interface QiitaApiService {
    @GET("items?per_page=10&page=1")
    Observable<List<QiitaItem>> items();
    
    // 他に API があればここに並べる
}
この例だと item() メソッドで Qiita API の items?per_page=10&page=1 に HTTP の GET メソッドでアクセスし、戻り値は RxJava の Observable 型(中身は先程 Gson モデルで定義した QiitaItem の List)です。
この API サービスのインスタンス化するには次のようにします。API の基準 URL はここで指定します。
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://qiita.com/api/v1/")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();
qiitaApiService = retrofit.create(QiitaApiService.class);
この API サービスのインスタンス(qiitaApiService)は何度も作成するのは無駄なので、アプリケーション全体で使いまわすようにします。方法は色々ありますが(自分なら Dagger2 を使いますが)、例えば Application クラスに保持する場合は次のようにします。
// ...
public class MainApplication extends Application {
    private QiitaApiService qiitaApiService = null;
    @Override
    public void onCreate() {
        super.onCreate();
    }
    public QiitaApiService getQiitaApiService() {
        if (qiitaApiService == null) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://qiita.com/api/v1/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
            qiitaApiService = retrofit.create(QiitaApiService.class);
        }
        return  qiitaApiService;
    }
}
もしくは static フィールドと static メソッドでインスンタンスの保持と配信をするような Provider を作成する場合は次のようにします。
public class Provider {
    private static QiitaApiService qiitaApiService = null;
    public static QiitaApiService provideQiitaApiService() {
        if (qiitaApiService == null) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://qiita.com/api/v1/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
            qiitaApiService = retrofit.create(QiitaApiService.class);
        }
        return qiitaApiService;
    }
}
API の利用
例えば Activity の onResume() で API にアクセスし結果をログに出力するコードは次のようになります。
// ...
public class MainActivity extends AppCompatActivity {
    private QiitaApiService qiitaApiService;
    private Subscription subscription;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        qiitaApiService = ((MainApplication) getApplication()).getQiitaApiService();
    }
    @Override
    protected void onResume() {
        super.onResume();
        // Qiitaの新着アイテムを取得
        subscription = qiitaApiService.items()
                .subscribeOn(Schedulers.io()) // バックグランドで実行
                .observeOn(AndroidSchedulers.mainThread()) // UIスレッドで購読
                .subscribe(aQiitaItemList -> {
                    // ログにタイトルを出力
                    for (QiitaItem qiitaItem: aQiitaItemList) {
                        Log.d("QiitaItem:", qiitaItem.title);
                    }
                });
    }
    @Override
    protected void onPause() {
        super.onPause();
        // 購読解除
        subscription.unsubscribe();
    }
}
結果は次のとおりです。
おわりに
今回のソースコードは GitHub に置きました。必要に応じて参照ください。
⇒ https://github.com/hkusu/android-rx-retrofit-example

