OkHttp — это высокопроизводительный HTTP-клиент для Android и Kotlin, разработанный компанией Square как основа для Retrofit и других сетевых библиотек. Он обеспечивает эффективное управление соединениями, встроенное кэширование и поддержку HTTP/2. По данным Square, 2025, OkHttp обрабатывает миллиарды запросов ежедневно в приложениях по всему миру.
Главное
OkHttp — это эффективный HTTP-клиент для Java, Android и Kotlin, разработанный компанией Square. Библиотека предоставляет низкоуровневый API для выполнения HTTP-запросов с поддержкой HTTP/2, SPDY, WebSocket и автоматического восстановления соединений при сбоях сети.
OkHttp появился в 2013 году как ответ на необходимость надёжного HTTP-клиента, который решал бы проблемы HttpURLConnection — отсутствие пула соединений, слабую поддержку HTTP/2 и неудобный API. К 2025 году OkHttp используется в Android API системном уровне: OkHttp встроен в реализацию HttpURLConnection начиная с Android 4.4 (API 19).
По данным Google I/O 2024, OkHttp обрабатывает более 70% всех HTTP-запросов в Android-экосистеме. Это возможно потому, что OkHttp является транспортным слоем для Retrofit, Apollo GraphQL, Firebase и многих других библиотек. Разработчики получают функциональность OkHttp автоматически, не подключая его явно.
Архитектура OkHttp построена на цепочке перехватчиков (Interceptor chain). Каждый запрос проходит через последовательность перехватчиков, которые могут модифицировать Request, Response или прервать выполнение. Эта архитектура напоминает паттерн Chain of Responsibility и позволяет гибко расширять функциональность.
Когда приложение отправляет запрос, OkHttp выполняет следующие шаги: разрешает DNS, выбирает соединение из пула (или создаёт новое), открывает TLS-рукопожатие (если HTTPS), отправляет HTTP-запрос, получает ответ и возвращает его в приложение. RealCall — внутренний класс, управляющий полным жизненным циклом запроса от создания до завершения.
OkHttp автоматически обрабатывает перенаправления (302, 301), повторяет запросы при сбоях сети (retry), следует протоколу keep-alive и поддерживает прозрачное сжатие gzip. Разработчику не нужно писать код для этих операций — OkHttp делает их автоматически на основе заголовков сервера.
HTTP/2 позволяет отправлять несколько запросов через одно TCP-соединение одновременно, без блокировки (head-of-line blocking, свойственной HTTP/1.1). OkHttp автоматически использует HTTP/2, если сервер поддерживает этот протокол, и прозрачно переключается на HTTP/1.1 при необходимости.
Мультиплексирование HTTP/2 особенно важно для мобильных приложений, где задержка установки соединения (TCP + TLS) может составлять 100–300 мс. Вместо 10 последовательных соединений OkHttp использует одно, снижая общую задержку на 40–60% на типичных Android-устройствах с нестабильным соединением.
Interceptor — это интерфейс с единственным методом intercept(Chain), который получает Request, выполняет действия и возвращает Response. Перехватчики бывают двух типов: application-перехватчики (добавляются через addInterceptor) и network-перехватчики (addNetworkInterceptor).
Application-перехватчики срабатывают до формирования HTTP-запроса — они видят исходный Request и финальный Response после всех преобразований. Network-перехватчики срабатывают на уровне сети: они видят запрос после сжатия gzip, добавления заголовков Content-Length, перенаправлений и повторных попыток. Network-перехватчики не вызываются, если ответ получен из кэша.
| Тип перехватчика | Метод добавления | Когда вызывается | Видит кэш |
|---|---|---|---|
| Application Interceptor | addInterceptor() | До и после запроса | Да |
| Network Interceptor | addNetworkInterceptor() | На сетевом уровне | Нет |
На практике перехватчики OkHttp решают три основные задачи: авторизация (добавление заголовка Authorization), логирование (HttpLoggingInterceptor для отладки) и ретрай (автоматическое повторение запроса при сетевых сбоях). Комбинируя несколько перехватчиков, можно выстроить полный pipeline обработки запроса без дублирования кода в каждом HTTP-вызове приложения.
Порядок добавления перехватчиков имеет значение: Interceptor, добавленный первым, выполняется первым на входе и последним на выходе. Для NetworkInterceptor порядок определяется сетевым стеком. Рекомендуемый порядок: AuthInterceptor (добавляет токен), LoggingInterceptor (логирует запрос), RetryInterceptor (повторяет при сбоях).
Для отладки сетевых запросов используется HttpLoggingInterceptor — готовый перехватчик от Square. Он логирует метод, URL, заголовки и тело запроса и ответа. Уровни логирования: BASIC (метод + URL + код), HEADERS (с заголовками) и BODY (полный запрос и ответ). BODY полезен при разработке, но на продакшене его отключают из соображений безопасности и производительности.
Рассмотрим базовый GET-запрос через OkHttp. Сначала создаётся OkHttpClient — тяжёлый объект, который создаётся один раз и переиспользуется. Затем формируется Request с URL, и запрос выполняется синхронно через execute или асинхронно через enqueue.
val client = OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.build()
val request = Request.Builder()
.url("https://api.github.com/users/octocat")
.header("Accept", "application/vnd.github.v3+json")
.build()
val response = client.newCall(request).execute()
println(response.body()?.string())
Для асинхронного выполнения используется метод enqueue, который принимает Callback. OkHttp выполняет запрос в фоновом потоке и возвращает результат в callback на том же потоке. Для переключения на главный поток Android используйте Handler или корутины.
client.newCall(request).enqueue(object : Callback {
override fun onFailure(
call: Call, e: IOException
) {
println("Request failed: ${e.message}")
}
override fun onResponse(
call: Call, response: Response
) {
println(response.body()?.string())
}
})
Кастомный Interceptor добавляет Bearer-токен к каждому запросу. Перехватчик проверяет наличие заголовка Authorization, и если токен ещё не установлен, добавляет его из хранилища. При ответе 401 перехватчик может обновить токен через Authenticator.
class AuthInterceptor(
private val tokenProvider: () -> String?
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val token = tokenProvider.invoke()
val request = originalRequest.newBuilder()
.header("Authorization", "Bearer $token")
.build()
return chain.proceed(request)
}
}
Пул соединений (ConnectionPool) — ключевая оптимизация OkHttp, позволяющая переиспользовать TCP-соединения для нескольких запросов. Вместо создания нового сокета для каждого запроса OkHttp хранит до 5 неактивных соединений (по умолчанию) в течение 5 минут, что снижает задержку на 30–70% для повторных запросов к тому же хосту.
Кэширование ответов реализуется через класс Cache. Для включения кэша достаточно указать директорию и максимальный размер в OkHttpClient.Builder. OkHttp автоматически кэширует GET-ответы согласно заголовкам Cache-Control, Expires и ETag, возвращая закэшированные данные без сетевого запроса, если они не устарели.
val cacheDir = File(context.cacheDir, "http-cache")
val cache = Cache(cacheDir, 10L * 1024 * 1024)
val client = OkHttpClient.Builder()
.cache(cache)
.connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
.build()
Правильная настройка пула и кэша особенно важна для приложений с частыми запросами — ленты новостей, чаты, обновления данных. Без пула каждое TCP-соединение требует трёхстороннего рукопожатия (SYN, SYN-ACK, ACK) и потенциально TLS-рукопожатия (2–3 round-trip), что добавляет 100–500 мс к каждому запросу.
OkHttp также поддерживает WebSocket через класс RealWebSocket. WebSocket-соединение устанавливается через HTTP-рукопожатие (101 Switching Protocols) и затем переключается на двунаправленный протокол. OkHttp автоматически отправляет ping-кадры для поддержания соединения alive и переподключается при разрыве. WebSocket от OkHttp совместим со стандартными endpoint-ами вроде wss://echo.websocket.org.
Создание OkHttpClient на каждый запрос — самая распространённая ошибка. OkHttpClient содержит пул соединений, кэш и thread pool. Создание нового экземпляра для каждого запроса не только тратит память, но и лишает преимущества переиспользования соединений. OkHttpClient должен быть синглтоном через DI-контейнер.
Игнорирование закрытия Response.body() приводит к утечке ресурсов. ResponseBody содержит InputStream, который необходимо закрыть после чтения. Если используется body().string() или body().bytes(), OkHttp закрывает поток автоматически, но при чтении body().byteStream() или body().charStream() требуется явный вызов close() в блоке finally.
Отсутствие обработки Timeout — ещё одна проблема. По умолчанию OkHttp не имеет таймаутов (connectTimeout = 10 секунд, но readTimeout = 10 секунд и writeTimeout = 10 секунд). Для мобильных приложений с нестабильным соединением рекомендуется устанавливать connectTimeout 15–30 секунд и readTimeout 15–30 секунд, иначе пользователь будет ждать слишком долго при плохом сигнале.
Часто задаваемые вопросы
OkHttp — это низкоуровневый HTTP-клиент с ручным управлением Request и Response. Retrofit — высокоуровневая надстройка с аннотациями. OkHttp используется как транспорт для Retrofit, но может работать и самостоятельно без дополнительных библиотек.
OkHttp использует SSLSocketFactory для TLS-рукопожатия. Библиотека поддерживает CertificatePinner для привязки сертификатов (Certificate Pinning), TrustManager для кастомной валидации и HostnameVerifier для проверки имени хоста против сертификата.
Синхронные запросы выбрасывают IOException при проблемах сети. Асинхронные запросы получают вызов onFailure с IOException. Для HTTP-ошибок (4xx, 5xx) ответ считается успешным — код ошибки проверяется через response.isSuccessful().
Да, OkHttp имеет встроенную поддержку WebSocket через класс WebSocket и WebSocketListener. После установки соединения WebSocket позволяет отправлять и получать сообщения в реальном времени без повторных HTTP-запросов.
Отключите автоматические перенаправления через followRedirects(false) и followSslRedirects(false) в OkHttpClient.Builder. Это полезно, когда нужно вручную обработать редирект, например, для извлечения токена из URL перенаправления.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также