OkHttp library

OkHttp is an HTTP client that’s efficient by default:

  • HTTP/2 support allows all requests to the same host to share a socket.
  • Connection pooling reduces request latency (if HTTP/2 isn’t available).
  • Transparent GZIP shrinks download sizes.
  • Response caching avoids the network completely for repeat requests.

Also OkHttp perseveres when the network is troublesome and try to resolve problems.

You can use single client for multiple requests. You can use client with default settings or create client via builder with custom settings.

Library page on GitHub. Official doc has useful recipes.

1. Add dependency

implementation("com.squareup.okhttp3:okhttp:4.10.0")

2. Create OkHttp client by default or manually using the builder.

OkHttp performs best when you create a single OkHttpClient instance and reuse it for all of your HTTP calls. This is because each client holds its own connection pool and thread pools.

val client = OkHttpClient() // default client

// custom client
val client: OkHttpClient = OkHttpClient.Builder()
      .connectTimeout(5, TimeUnit.SECONDS)
      .writeTimeout(5, TimeUnit.SECONDS)
      .readTimeout(5, TimeUnit.SECONDS)
      .callTimeout(10, TimeUnit.SECONDS)
      .cache(Cache(
          directory = cacheDirectory,
          maxSize = 10L * 1024L * 1024L // 10 MiB
      ))
      .addInterceptor(FooInterceptor())
      .build()

3. Create a request and execute it synchronously or asynchronously.

  • execute() - execute request synchronously
  • enqueue() - execute request asynchronously
// execute request synchronously
client.newCall(request).execute().use { response ->
    if (!response.isSuccessful) throw IOException("Unexpected code $response")

    // do something
}

// execute request asynchronously 
client.newCall(request).enqueue(object : Callback {
      override fun onFailure(call: Call, e: IOException) {
        e.printStackTrace()
      }

      override fun onResponse(call: Call, response: Response) {
        response.use {
          if (!response.isSuccessful) throw IOException("Unexpected code $response")

          // do something
        }
      }
    })
dowload text, i.e. GET string
POST string
POST stream
POST file
POST multipart file
download json
download file

interceptors

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.

Interceptors are registered as either application or network interceptors. Each interceptor chain has relative merits.

Application interceptors:

  • Don’t need to worry about intermediate responses like redirects and retries.
  • Are always invoked once, even if the HTTP response is served from the cache.
  • Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match.
  • ermitted to short-circuit and not call Chain.proceed().
  • Permitted to retry and make multiple calls to Chain.proceed().
  • Can adjust Call timeouts using withConnectTimeout, withReadTimeout, withWriteTimeout.

Network interceptors:

  • Able to operate on intermediate responses like redirects and retries.
  • Not invoked for cached responses that short-circuit the network.
  • Observe the data just as it will be transmitted over the network.
  • Access to the Connection that carries the request.
Logging intercepter
Rewrite request example
Rewrite response example