← Назад к вопросам

Для чего нужен OkHttp?

2.3 Middle🔥 181 комментариев
#Сетевое взаимодействие

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

OkHttp в Android разработке

OkHttp — это мощная и гибкая HTTP клиент библиотека для Java и Kotlin. Она используется для отправки HTTP запросов и работает на всех платформах. Это один из самых популярных choice для работы с REST API в Android.

Основное назначение

OkHttp — это HTTP клиент, который:

  • Отправляет HTTP запросы (GET, POST, PUT, DELETE и т.д.)
  • Получает ответы от сервера
  • Управляет подключениями к сети
  • Обрабатывает ошибки сети
  • Кеширует ответы
  • Автоматически повторяет неудачные запросы

Почему OkHttp, а не встроенный URLConnection?

Лучше производительность

  • HTTP/2 поддержка (multiplexing)
  • Connection pooling
  • Gzip сжатие автоматически

Удобство

  • Простой и понятный API
  • Меньше boilerplate кода
  • Автоматическое управление соединениями

Features

  • Кеширование
  • Retry logic
  • Interceptors (middleware)
  • TLS/SSL поддержка

Надежность

  • Используется в Retrofit, Picasso, Glide
  • Используется Google, Facebook, Square
  • Активно поддерживается

Пример базового использования

// Зависимость в build.gradle
compile 'com.squareup.okhttp3:okhttp:4.10.0'

// Создание OkHttp клиента
val client = OkHttpClient()

// Создание простого GET запроса
val request = Request.Builder()
    .url("https://api.github.com/users/octocat")
    .build()

// Выполнение запроса
val response = client.newCall(request).execute()
println(response.body?.string())  // получаем ответ

Основные операции

1. GET запрос

val request = Request.Builder()
    .url("https://api.example.com/users/123")
    .get()
    .build()

val response = client.newCall(request).execute()
if (response.isSuccessful) {
    val body = response.body?.string()
    println(body)
} else {
    println("Error: ${response.code}")
}

2. POST запрос с JSON

val json = """{
    "name": "John",
    "email": "john@example.com"
}""".trimIndent()

val body = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
    .url("https://api.example.com/users")
    .post(body)
    .build()

val response = client.newCall(request).execute()

3. Асинхронный запрос (правильный подход)

val request = Request.Builder()
    .url("https://api.example.com/users")
    .build()

client.newCall(request).enqueue(object : Callback {
    override fun onFailure(call: Call, e: IOException) {
        println("Network error: ${e.message}")
    }
    
    override fun onResponse(call: Call, response: Response) {
        if (response.isSuccessful) {
            val body = response.body?.string()
            println("Success: $body")
        } else {
            println("Error: ${response.code}")
        }
    }
})

Конфигурация OkHttp клиента

1. Добавление Interceptor'ов (логирование, headers и т.д.)

val client = OkHttpClient.Builder()
    .addInterceptor { chain ->
        val originalRequest = chain.request()
        
        // Добавляем header к каждому запросу
        val newRequest = originalRequest.newBuilder()
            .header("Authorization", "Bearer token123")
            .header("Accept", "application/json")
            .build()
        
        println("Отправляем: ${newRequest.method} ${newRequest.url}")
        
        val response = chain.proceed(newRequest)
        
        println("Ответ: ${response.code}")
        
        response
    }
    .build()

2. Кеширование

val cacheDir = File(context.cacheDir, "http_cache")
val cache = Cache(cacheDir, 10 * 1024 * 1024)  // 10 MB

val client = OkHttpClient.Builder()
    .cache(cache)
    .build()

// Теперь OkHttp автоматически кеширует ответы
val request = Request.Builder()
    .url("https://api.example.com/data")
    .build()

val response = client.newCall(request).execute()
// Второй запрос вернёт кешированный ответ (если valid)

3. Timeout'ы

val client = OkHttpClient.Builder()
    .connectTimeout(30, TimeUnit.SECONDS)  // подключение
    .readTimeout(30, TimeUnit.SECONDS)     // чтение ответа
    .writeTimeout(30, TimeUnit.SECONDS)    // отправка запроса
    .build()

4. Retry logic

val client = OkHttpClient.Builder()
    .retryOnConnectionFailure(true)  // автоматический retry
    .build()

// Или через interceptor
.addInterceptor { chain ->
    var attempt = 0
    var request = chain.request()
    while (true) {
        try {
            return@addInterceptor chain.proceed(request)
        } catch (e: IOException) {
            attempt++
            if (attempt > 3) throw e
            println("Retry attempt $attempt")
        }
    }
}

OkHttp в практике Android разработки

1. С Retrofit (самая частая комбинация)

// Retrofit под капотом использует OkHttp
val client = OkHttpClient.Builder()
    .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .client(client)  // используем наш OkHttp
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val apiService = retrofit.create(ApiService::class.java)

2. Логирование запросов

val loggingInterceptor = HttpLoggingInterceptor { message ->
    Log.d("OkHttp", message)
}.apply {
    level = HttpLoggingInterceptor.Level.BODY  // логирует всё
}

val client = OkHttpClient.Builder()
    .addInterceptor(loggingInterceptor)
    .build()

3. Добавление токена авторизации

val client = OkHttpClient.Builder()
    .addInterceptor { chain ->
        val originalRequest = chain.request()
        val newRequest = originalRequest.newBuilder()
            .header("Authorization", "Bearer ${authManager.getToken()}")
            .build()
        chain.proceed(newRequest)
    }
    .build()

Основные Features OkHttp

FeatureОписаниеПример
HTTP/2Multiplexing, улучшение performanceАвтоматически
Connection poolingПереиспользование соединенийВстроено
CachingКеширование ответов.cache(cache)
CompressionGzip сжатиеАвтоматически
InterceptorsMiddleware для запросов/ответов.addInterceptor()
TimeoutsУправление timeout'ами.connectTimeout()
RetriesАвтоматический retry.retryOnConnectionFailure()
TLS/SSLБезопасное соединениеВстроено

OkHttp vs Retrofit vs HttpURLConnection

ПараметрURLConnectionOkHttpRetrofit
УровеньLow-levelMid-levelHigh-level
ПростотаСложноПростоОчень просто
FeaturesМинимумМногоВсё
JSON parsingНетНетДа (с Gson/Moshi)
Когда использоватьРедкоAPI запросыREST API с моделями

Best Practices

Используй Singleton для OkHttpClient

class AppModule {
    companion object {
        private var httpClient: OkHttpClient? = null
        
        fun getHttpClient(): OkHttpClient {
            return httpClient ?: OkHttpClient.Builder()
                .build()
                .also { httpClient = it }
        }
    }
}

Не создавай новый клиент для каждого запроса

// ❌ Плохо
for (i in 1..100) {
    val client = OkHttpClient()  // создаём 100 клиентов!
    client.newCall(request).execute()
}

// ✅ Хорошо
for (i in 1..100) {
    singletonClient.newCall(request).execute()  // используем один
}

Закрывай Response body

val response = client.newCall(request).execute()
try {
    println(response.body?.string())
} finally {
    response.close()  // важно!
}

Не игнорируй timeout'ы

// ❌ Может зависнуть навечно
val client = OkHttpClient()

// ✅ Правильно
val client = OkHttpClient.Builder()
    .connectTimeout(30, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build()

Заключение

OkHttp — это стандартная библиотека для HTTP запросов в Android. Она:

  • Используется во всех крупных проектах
  • Обеспечивает performance и reliability
  • Имеет гибкую систему interceptor'ов
  • Автоматически управляет соединениями и кешированием

В 99% случаев в Android ты используешь OkHttp либо напрямую, либо через Retrofit. Понимание как она работает — необходимо для любого Android разработчика.

Для чего нужен OkHttp? | PrepBro