LoginSignup
57
39

More than 5 years have passed since last update.

OkHttp3はシングルトンにすべし

Last updated at Posted at 2017-01-31

はじめに

OkHttp2とOkHttp3とでコネクションプールの部分が大きく変わっている。
Change Logからの引用。

There is no longer a global singleton connection pool. In OkHttp 2.x, all OkHttpClient instances shared a common connection pool by default. In OkHttp 3.x, each new OkHttpClient gets its own private connection pool. Applications should avoid creating many connection pools as doing so prevents connection reuse. Each connection pool holds its own set of connections alive so applications that have many pools also risk exhausting memory!

上記からわかるように、OkHttp2まではコネクションプールを共有していたのが、OkHttp3からはコネクションプールを各インスタンスごとに別々で持つようになった。
それを知らずにOkHttpを新しくインスタンス生成し続けると、OutOfMemoryErrorになりかねない。
なので、OkHttp3はシングルトンで書くとよい。

サンプルコード

とりあえず、シングルトンで書いてみました。
もっとこうしたほうがいいとかあったらコメントください。

OkHttpSingleton.java

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class OkHttpSingleton {

    private OkHttpClient mOkHttpClient;

    private static OkHttpSingleton ourInstance = new OkHttpSingleton();

    public static OkHttpSingleton getInstance() {
        return ourInstance;
    }

    private OkHttpSingleton() {

        OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
        okHttpBuilder.connectTimeout(20, TimeUnit.SECONDS);
        okHttpBuilder.readTimeout(15, TimeUnit.SECONDS);
        okHttpBuilder.writeTimeout(15, TimeUnit.SECONDS);
        okHttpBuilder.addInterceptor(getInterceptor());

        mOkHttpClient = okHttpBuilder.build();
    }

    private Interceptor getInterceptor() {

        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {

                Request newRequest = chain.request().newBuilder()
                        .addHeader("Accept", "application/json")
                        .build();

                return chain.proceed(newRequest);
            }
        };
    }

    public OkHttpClient getOkHttpClient() {
        return mOkHttpClient;
    }
}

リクエストヘッダーを共通にする場合は、OkHttpClientのInterceptorを使うとよい。

OkHttpClientの設定(タイムアウト時間など)を個別に変更したい場合は、OkHttpClient.newBuilder()を使って書き換える。


OkHttpClient copy = client.newBuilder()
          .readTimeout(500, TimeUnit.MILLISECONDS)
          .build();

参考

57
39
1

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
57
39