LoginSignup
34
30

More than 5 years have passed since last update.

Retrofit2 + OkHttp + RxAndroid + Jackson + Realm で開発環境構築

Last updated at Posted at 2015-12-01

2016/3/11にRetrofitが正式にversion2となりました。
アップデートしてみましたが、基本は以下の記述で問題ありません。
パッケージ名とprogurardあたりを修正すればビルドは通ると思います。

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;

Retrofitがversion2になりました。(12/1現在beta)
どうせなら最新でアプリを作ろうとした時のメモです。情報があまりなかったので誰かのためになれば幸いです。

環境構築

MacOS X 10.11.1
Android Studio 1.5
SDK API 23
Build Tools Version 23.0.2

Gradle

抜粋です。JacksonにバグがあるのでpackagingOptionsに無視するファイルを書く必要あり。

build.gradle
android {
  ...
  packagingOptions {
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/ASL2.0'
    exclude 'META-INF/services/javax.annotation.processing.Processor'
  }
}


dependencies {
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.squareup.retrofit2:retrofit:2.0.0'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0'
    compile 'com.squareup.retrofit2:converter-jackson:2.0.0'
    compile ('com.squareup.okhttp3:okhttp:3.2.0') {
        exclude module: 'okhttp'
    }
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'
    compile 'io.reactivex:rxandroid:1.0.1'
    compile 'io.realm:realm-android:0.86.0'
}

Proguard

Realmのドキュメントにも記載ありますが、以下をproguardに追加。

proguard-rules.pro
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class *
-dontwarn javax.**
-dontwarn io.realm.**

実装

/hoge.json へ接続し値を取得することを想定します。

hoge.jon
{
  'title' : 'タイトルです',
  'link' : 'リンクです',
  'description' : '詳細です'
}

Entity

hoge.jsonのentityです。変数名(getter/setter)でJacksonがパースを行います。Gsonはprivateフィールドを直接読みに行くため、Realmとの相性が悪いです。

hoge.java
public class Hoge extends RealmObject implements Serializable {
    private String title;
    private String link;
    private String description;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

HogeはRealmオブジェクトとして保存したいためにextends, Bundleで渡すことを想定しSerializableをimplementsしてます。

API

まずはインターフェースを定義します。

apiservice.java
public interface ApiService {

    @GET("/hoge.json")
    Observable<Hoge> loadHoge();

    // 今回は引数はないですが、こんな感じになる
    //@GET("/hoge.json?query={query}")
    //Observable< Hoge > loadHoge(@Path("query") String query);
}

次にretrofitを管理するManagerクラスを実装します。

apimanager.java
public class ApiManager {

    private static ApiService apiService;

    // volatile = 最適化の抑止
    static volatile Retrofit retrofit = null;

    private ApiManager(){}

    public static Retrofit getRetrofit() {
        if (retrofit == null) {
            synchronized (ApiManager.class) {
                if (retrofit == null) {
                    ObjectMapper mapper = new ObjectMapper();
                    JacksonConverterFactory factory = JacksonConverterFactory.create(mapper);
                    OkHttpClient client = new OkHttpClient();
                    retrofit = new Retrofit.Builder()
                            .baseUrl("https://hogeexample.com/")
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            .addConverterFactory(factory)
                            .client(client)
                            .build();
                }
            }
        }

        return retrofit;
    }

    public static void initApiService() {
        if (apiService == null) {
            synchronized (ApiManager.class) {
                if (apiService == null) {
                    apiService = getRetrofit().create(ApiService.class);
                }
            }
        }
    }

    public static ApiService getApiService() {
        initApiService();
        return apiService;
    }
}

これを使用するとこうなります。

apitest.java
@RunWith(AndroidJUnit4.class)
public class ApiTest {

    @Test
    public void Hogeを取得する() throws Exception {

        ApiService apiService = ApiManager.getApiService();
        Observable<Hoge> observeLoadHoge = apiService.loadHoge();

        observeLoadHoge.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Hoge>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        Assert.fail(e.toString());
                    }

                    @Override
                    public void onNext(Hoge hoge) {
                        Assert.assertNotNull(hoge);
                    }
                });
    }
}

Github

ご要望があれば

アプリ作りました。

NewsFeeder です。
サクッと今注目されている記事を見るのに便利です。
iOSは弊社インターンが開発し、現在申請中です。

お仕事募集しております

株式会社クランクでは、お仕事を募集しております。
サーバーサイド、クライアントサイド(JS, iOS, Android)を一貫して開発可能です。
弊社サイトにて案件実績を掲載しております。
またパートナー(フリーランス)、バイト、インターンの募集も行ってます。
エンジニア、サイクリストからのメッセージお待ちしております。

34
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
30