SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

BizReach Tech Blog

Android 8.0とAndroid Studio 3.0で始めるReactive Extensionsを用いたアプリ開発

BizReach Tech Blog 第2回


  • X ポスト
  • このエントリーをはてなブックマークに追加

通信処理を実装する

 通信は下図に示すように、okhttp、Retrofit、google-gson、RxJavaを連携させて利用します。

 build.gradleは下記のように記載します。adapter-rxjava2はRetrofit2のレスポンスをRxJava2に連携するためのライブラリ、logging-interceptorはokhttpの通信ログを出力するためのライブラリです。

dependencies {
    ...略...
    
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    
    compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'
    
    ...略...
}

 対応するProGuard設定は以下のとおりです。

-dontwarn javax.annotation.**

# okhttp
-dontwarn okhttp3.**
-dontwarn okio.**

# Retrofit
-dontnote retrofit2.Platform
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes Exceptions

APIインターフェースを定義

 今回はユーザーリスト取得APIとしてrandomuser.meを利用させてもらいます。randomuser.meは、ランダムにダミーのユーザー情報を生成するサービスです。

 APIインターフェースはRetrofitライブラリが提供する各種のアノテーションを用いて定義します。@GETアノテーションにリクエストパスを指定し、@Queryパラメータでリクエストパラメータを指定します。そして、レスポンスはio.reactivex.Observableを指定することでRxJavaを用いたハンドリングができるようにします。

/**
 * Api Interface
 */
public interface Api {
    /**
     * ユーザー一覧を取得します。
     *
     * @param page ページ番号
     * @return {@link RandomUserResponse}
     */
    @GET("api?results=20&seed=hoge&nat=us")
    Observable<RandomUserResponse> list(@Query("page") final Integer page);
}

 上記の例は、https://randomuser.me/apiに対して、取得件数を20(result=20)、リスト固定(seed=hoge)、英語圏のユーザー(nat=us)を固定条件、ページ番号(page)を可変条件として付与し、GETリクエストを送信する定義です。

HTTPクライアントビルダーを用意

 HTTPクライアントはHTTP2.0にも対応しているokhttpライブラリを利用します。アプリ内におけるHTTP通信の基本設定を統一するため、Applicationクラスにokhttpクライアントビルダー生成処理を実装するのが良いと思います。

public class ChatApplication extends Application {
    ...
    
    /**
     * {@link OkHttpClient.Builder}を生成します。
     *
     * @return {@link OkHttpClient.Builder}
     */
    public static OkHttpClient.Builder httpClientBuilder() {
        // HTTP通信ログをTimber経由で出力
        final HttpLoggingInterceptor logging = new HttpLoggingInterceptor(Timber::d);
        logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
        
        return new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .addInterceptor(logging);
    }
    
    ...
}

Retrofitビルダーを用意

 APIアクセスを行うためのRetrofitビルダー生成処理も同様にApplicationクラスに実装しておきます。

public class ChatApplication extends Application {
    // AsyncTaskの実装を参考にスレッドプールサイズを定義
    private static final int CPU_COUNT
            = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE
            = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    
    private Executor mThreadPoolExecutor;
    
    /**
     * Get thread pool executor.
     *
     * @return {@link Executor}
     */
    public Executor getThreadPoolExecutor() {
        if (mThreadPoolExecutor == null) {
            mThreadPoolExecutor = Executors.newFixedThreadPool(CORE_POOL_SIZE);
        }
        
        return mThreadPoolExecutor;
    }
    
    ...
    
    /**
     * {@link Retrofit.Builder}を生成します。
     *
     * @return {@link Retrofit.Builder}
     */
    public static Retrofit.Builder retrofitBuilder() {
        final Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        
        return new Retrofit.Builder()
                .callbackExecutor(getInstance().getThreadPoolExecutor())
                // レスポンスをgoogle-gsonでパース
                .addConverterFactory(GsonConverterFactory.create(gson))
                // RetrofitとRxJavaを連携
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create());
    }
    
    ...
}

APIアクセサの実装

 前述のAPIインターフェース定義、HTTPクライアントビルダー、Retrofitビルダーを用いてAPIアクセスの準備を行うためのクラスを実装します。ここをシングルトン実装にしておくことで、APIエンドポイントごとにHTTPクライアントインスタンスを使いまわすようにしています。okhttp3はインスタンスごとにコネクションプールを持つため、インスタンスを生成し過ぎるとメモリ消費に悪影響を与えてしまいます。

/**
 * randomuser.me APIアクセサクラス
 */
public class RandomUserApi {
    private static final String ORIGIN = "https://randomuser.me";
    
    private static RandomUserApi instance;
    
    private Api mInterface;
    
    /**
     * randomuser.me Apiインターフェースを取得します。
     *
     * @return {@link Api}
     */
    public static Api get() {
        synchronized (RandomUserApi.class) {
            if (instance == null) {
                instance = new RandomUserApi();
            }
        }
        return instance.mInterface;
    }
    
    /**
     * コンストラクタ
     */
    private RandomUserApi() {
        mInterface = ChatApplication.retrofitBuilder()
                .client(ChatApplication.httpClientBuilder().build())
                .baseUrl(ORIGIN)
                .build()
                .create(Api.class);
    }
    
    ...
}

次のページ
ユーザー一覧を取得して表示する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
BizReach Tech Blog連載記事一覧

もっと読む

この記事の著者

岩井 友希(株式会社ビズリーチ)(イワイ トモキ)

SIer、フリーランスを経て、2015年にビズリーチへ入社。 Java、Python、Android、iOS、Linuxたまにセキュリティとかのキーワードに反応するエンジニアです。 github:https://github.com/TomokiIwai 株式会社ビズリーチについて:https://www.bizreach.co.jp/recruit/

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10676 2018/10/17 15:47

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング