Android path · The screen and its data · Topic 8 of 12

Networking with Retrofit and OkHttp

Not started

Your app needs the INTERNET permission (a normal permission, granted at install) and a thread that isn't the main one. Most Android apps use OkHttp as the HTTP client and Retrofit on top of it to turn an annotated Kotlin interface into calls. With coroutines, a request is just a suspend function that returns your parsed type or throws.

Why it matters: Mobile networks are slow, flaky and metered. The defaults decide whether a dead connection hangs a screen for ten seconds or forever, and whether a repeat request costs a round trip.

  1. 1Never on the main thread

    Android throws NetworkOnMainThreadException by default. Retrofit's suspend functions move the call off it for you.

  2. 2One OkHttpClient

    Share a single client so connections, the thread pool and the cache are reused.

  3. 3Timeouts are per phase

    OkHttp's connect, read and write timeouts default to 10 seconds each; the whole-call timeout defaults to none.

  4. 4HTTPS by default

    Since Android 9 (API 28) cleartext HTTP is blocked by default; the network security config controls exceptions.

1

How it works

The explanation, with examples you can run.

The client and the API

interface ShopApi {    @GET("products/{id}")    suspend fun product(@Path("id") id: String): ProductDto} val client = OkHttpClient.Builder()    .connectTimeout(10, TimeUnit.SECONDS)    .readTimeout(15, TimeUnit.SECONDS)    .callTimeout(30, TimeUnit.SECONDS)             // bounds the whole call; default is no limit    .cache(Cache(File(context.cacheDir, "http"), 20L * 1024 * 1024))    .build() val api = Retrofit.Builder()    .baseUrl("https://api.example.com/")    .client(client)    .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))    .build()    .create(ShopApi::class.java)

Retrofit runs suspend calls on OkHttp's own threads, so calling api.product(id) from viewModelScope is main-safe. A non-2xx response throws HttpException; a connection problem throws an IOException. Return Response<T> instead if you want to inspect status codes without exceptions.

Timeouts

OkHttp's defaults are 10 seconds for connect, read and write, and 0 (no limit) for the call timeout. Read and write timeouts measure the gap between packets, so a trickling response can run on far longer than 10 seconds. A callTimeout puts a ceiling on everything: DNS, connect, TLS, redirects, the body. Coroutine cancellation (the user leaves the screen and viewModelScope is cancelled) cancels the underlying OkHttp call too.

Caching

With a Cache installed, OkHttp follows standard HTTP caching: it serves fresh responses from disk using Cache-Control and revalidates stale ones with ETag/If-None-Match or Last-Modified, turning a full download into a 304 Not Modified. Getting the headers right on the server does most of the work. An Interceptor can add headers to every request (auth tokens, a user agent); an authenticator can refresh tokens when a request gets a 401.

Security

From Android 9 (API 28), cleartext HTTP is disabled by default. The network security configuration (res/xml/network_security_config.xml) lets you allow cleartext for a specific debug host, trust extra CAs in debug builds only, or pin certificates, without code. Treat pinning carefully: a pin that no longer matches the server's certificate breaks every installed copy until users update.

Flaky networks

  • Retry idempotent requests with backoff, not in a tight loop, and not for 4xx errors.
  • Check connectivity with ConnectivityManager to show an offline state, but don't treat it as a guarantee: "connected" doesn't mean the server is reachable.
  • For uploads that must eventually happen, hand them to WorkManager with a network constraint instead of retrying in the ViewModel.
  • Keep the network out of the UI: a repository fetches, writes to Room, and the UI observes the database.

Version note: OkHttp 4 and 5 are both in wide use; the builder APIs shown here exist in both.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.An OkHttpClient is built with default settings. A server accepts the connection and then sends one byte every 9 seconds. What happens?
  2. 2.Why create one OkHttpClient for the app instead of one per request?
  3. 3.Your app targets API 35 and calls http://api.example.com. What happens?

0 of 3 right so far. Get all three to finish this topic.