Налаштування OkHttp для сітьових запитів в Android-додатку
OkHttp — HTTP-клієнт, на якому побудовані Retrofit, Coil, Glide та більшість Android-бібліотек, що працюють з мережею. Використовуйте OkHttp напрямку, коли потрібен повний контроль: WebSocket-з'єднання, кастомні протоколи, загрузка файлів з прогресом, специфічна обробка заголовків — те, що у Retrofit або неможливо, або потребує обходних шляхів.
Коли OkHttp напрямку, а не через Retrofit
WebSocket: OkHttpClient.newWebSocket(request, listener) — нативна підтримка без додаткових залежностей. WebSocketListener отримує колбеки onOpen, onMessage, onFailure, onClosed. Для автоматичного реконекту потрібна власна логіка з exponential backoff.
Загрузка та выгрузка файлів з прогресом. Retrofit дозволяє завантажувати файли через @Multipart, але відслідкувати прогрес можна тільки через кастомний RequestBody, який обгортає джерело та викликає callback при запису байтів. Це OkHttp-рівень.
Кастомна аутентифікація. Authenticator інтерфейс OkHttp викликається при 401, дозволяє синхронно отримати новий токен та повторити запрос. З Retrofit це теж працює, але через OkHttpClient.
Спільний HTTP-клієнт для кількох бібліотек. Coil приймає OkHttpClient у ImageLoader.Builder, Retrofit — у Retrofit.Builder. Один налаштований клієнт зі спільним connection pool та кешем — замість кількох окремих клієнтів з дублюючою логікою.
Конфігурація OkHttpClient
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.cache(Cache(cacheDir, 10 * 1024 * 1024)) // 10 МБ кеш
.addInterceptor(authInterceptor)
.addInterceptor(loggingInterceptor)
.addNetworkInterceptor(networkMonitorInterceptor)
.authenticator(tokenRefreshAuthenticator)
.connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
.build()
addInterceptor vs addNetworkInterceptor: application-інтерсептори викликаються один раз та видять кешовані відповіді. Network-інтерсептори — тільки для реальних сітьових запитів. Для логування byte трафіку — network interceptor. Для додавання заголовків аутентифікації — application interceptor.
HTTP-кеш: Cache з правильним cache-dir (зазвичай context.cacheDir) прискорює повторні запитання та працює в offline, якщо сервер відправляє Cache-Control заголовки. Якщо не відправляє — ForceCacheInterceptor з примусовим FORCE_CACHE для offline.
Certificate pinning: CertificatePinner.Builder().add("api.example.com", "sha256/AAAA...").build(). SHA-256 fingerprint отримується з сертифіката через openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64. Pinning ломає з'єднання при ротації сертифіката — потрібно заздалегідь додавати новий fingerprint.
Типові помилки
Створення OkHttpClient на кожен запрос. Клієнт зберігає thread pool, connection pool та кеш — це має бути синглтон. У Hilt — @Singleton у @Provides.
Блокуючи операції всередину Interceptor. Interceptor.intercept() викликається на OkHttp dispatcher threads, але якщо робити suspend-функцію через runBlocking — це блокує dispatcher thread. Для async операцій у інтерсепторі (наприклад, refresh токена) використовуйте synchronized блок з умовною змінною, або виносимо refresh у Authenticator, який синхронний за контрактом.
Тестування: MockWebServer з com.squareup.okhttp3:mockwebserver — стандартний інструмент для unit-тестів сітьового шару. Піднімає локальний сервер, приймає запитання, повертає заготовлені відповіді.
Налаштування OkHttp з інтерсепторами, кешем, WebSocket або загрузкою файлів — 1-3 дні. Вартість розраховується індивідуально.







