##はじめに
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はシングルトンで書くとよい。
##サンプルコード
とりあえず、シングルトンで書いてみました。
もっとこうしたほうがいいとかあったらコメントください。
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();
##参考