Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
36
Help us understand the problem. What is going on with this article?
@taki4227

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

More than 3 years have passed since last update.

はじめに

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();

参考

36
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
taki4227
中小企業のSIer、ベンチャー企業を経て、今はSHOWROOMのエンジニアをしています。Android・iOS・Flutterでアプリ開発をしてきました。良いものを作って届けたい、良いものを作ることに携わりたい。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
36
Help us understand the problem. What is going on with this article?