OkHttp je vysoce výkonný HTTP klient pro Android a Kotlin, vyvinutý společností Square jako základ pro Retrofit a další síťové knihovny. Zajišťuje efektivní správu spojení, vestavěné ukládání do mezipaměti a podporu HTTP/2. Podle údajů Square, 2025, OkHttp zpracovává miliardy požadavků denně v aplikacích po celém světě.
Hlavní body
OkHttp je efektivní HTTP klient pro Java, Android a Kotlin, vyvinutý společností Square. Knihovna poskytuje nízkoúrovňové API pro provádění HTTP požadavků s podporou HTTP/2, SPDY, WebSocket a automatického obnovení spojení při výpadcích sítě.
OkHttp se objevil v roce 2013 jako odpověď na potřebu spolehlivého HTTP klienta, který by řešil problémy HttpURLConnection — chybějící pool spojení, slabou podporu HTTP/2 a nepohodlné API. Do roku 2025 je OkHttp používáno na systémové úrovni Android API: OkHttp je zabudováno do implementace HttpURLConnection od Androidu 4.4 (API 19).
Podle údajů Google I/O 2024 zpracovává OkHttp více než 70% všech HTTP požadavků v ekosystému Android. To je možné, protože OkHttp je transportní vrstvou pro Retrofit, Apollo GraphQL, Firebase a mnoho dalších knihoven. Vývojáři získávají funkcionalitu OkHttp automaticky, aniž by jej explicitně připojovali.
Architektura OkHttp je postavena na řetězci zachytávačů (Interceptor chain). Každý požadavek prochází sekvencí zachytávačů, které mohou upravit Request, Response nebo přerušit provádění. Tato architektura připomíná vzor Chain of Responsibility a umožňuje flexibilní rozšiřování funkcionality.
Když aplikace odešle požadavek, OkHttp provádí následující kroky: řeší DNS, vybírá spojení z poolu (nebo vytváří nové), otevírá TLS handshake (pokud je HTTPS), odesílá HTTP požadavek, přijímá odpověď a vrací ji aplikaci. RealCall je interní třída, která spravuje celý životní cyklus požadavku od vytvoření po dokončení.
OkHttp automaticky zpracovává přesměrování (302, 301), opakuje požadavky při výpadcích sítě (retry), dodržuje protokol keep-alive a podporuje transparentní kompresi gzip. Vývojář nemusí psát kód pro tyto operace — OkHttp je provádí automaticky na základě hlaviček serveru.
HTTP/2 umožňuje odesílat několik požadavků přes jedno TCP spojení současně, bez blokování (head-of-line blocking, charakteristické pro HTTP/1.1). OkHttp automaticky používá HTTP/2, pokud server podporuje tento protokol, a transparentně přepíná na HTTP/1.1 v případě potřeby.
Multiplexování HTTP/2 je obzvláště důležité pro mobilní aplikace, kde zpoždění navázání spojení (TCP + TLS) může být 100–300 ms. Místo 10 po sobě jdoucích spojení používá OkHttp jedno, čímž snižuje celkové zpoždění o 40–60% na typických zařízeních Android s nestabilním spojením.
Interceptor je rozhraní s jedinou metodou intercept(Chain), které přijímá Request, provádí akce a vrací Response. Zachytávače jsou dvou typů: aplikační zachytávače (přidávané přes addInterceptor) a síťové zachytávače (addNetworkInterceptor).
Aplikační zachytávače se aktivují před vytvořením HTTP požadavku — vidí původní Request a konečný Response po všech transformacích. Síťové zachytávače se aktivují na síťové úrovni: vidí požadavek po kompresi gzip, přidání hlaviček Content-Length, přesměrováních a opakovaných pokusech. Síťové zachytávače nejsou volány, pokud je odpověď získána z mezipaměti.
| Typ zachytávače | Metoda přidání | Kdy je volán | Vidí mezipaměť |
|---|---|---|---|
| Application Interceptor | addInterceptor() | Před a po požadavku | Ano |
| Network Interceptor | addNetworkInterceptor() | Na síťové úrovni | Ne |
V praxi zachytávače OkHttp řeší tři hlavní úkoly: autorizaci (přidání hlavičky Authorization), logování (HttpLoggingInterceptor pro ladění) a opakování (automatické opakování požadavku při výpadcích sítě). Kombinováním několika zachytávačů lze vybudovat kompletní pipeline zpracování požadavku bez duplikování kódu v každém HTTP volání aplikace.
Pořadí přidávání zachytávačů má význam: Interceptor přidaný první se provádí první na vstupu a poslední na výstupu. Pro NetworkInterceptor je pořadí určeno síťovým zásobníkem. Doporučené pořadí: AuthInterceptor (přidává token), LoggingInterceptor (loguje požadavek), RetryInterceptor (opakuje při výpadcích).
Pro ladění síťových požadavků se používá HttpLoggingInterceptor — hotový zachytávač od Square. Loguje metodu, URL, hlavičky a tělo požadavku a odpovědi. Úrovně logování: BASIC (metoda + URL + kód), HEADERS (s hlavičkami) a BODY (plný požadavek a odpověď). BODY je užitečný při vývoji, ale v produkci je vypnut z bezpečnostních a výkonnostních důvodů.
Podívejme se na základní GET požadavek přes OkHttp. Nejprve se vytvoří OkHttpClient — těžký objekt, který se vytvoří jednou a znovu používá. Poté se vytvoří Request s URL a požadavek se provede synchronně přes execute nebo asynchronně přes 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())
Pro asynchronní provedení se používá metoda enqueue, která přijímá Callback. OkHttp provádí požadavek na vlákně na pozadí a vrací výsledek v callbacku na stejném vlákně. Pro přepnutí na hlavní vlákno Androidu použijte Handler nebo korutiny.
client.newCall(request).enqueue(object : Callback {
override fun onFailure(
call: Call, e: IOException
) {
println("Požadavek selhal: ${e.message}")
}
override fun onResponse(
call: Call, response: Response
) {
println(response.body()?.string())
}
})
Vlastní Interceptor přidává Bearer token ke každému požadavku. Zachytávač kontroluje přítomnost hlavičky Authorization, a pokud token ještě není nastaven, přidá jej z úložiště. Při odpovědi 401 může zachytávač obnovit token pomocí 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)
}
}
Pool spojení (ConnectionPool) — klíčová optimalizace OkHttp, umožňující opětovné použití TCP spojení pro více požadavků. Místo vytváření nového socketu pro každý požadavek ukládá OkHttp až 5 neaktivních spojení (ve výchozím nastavení) po dobu 5 minut, což snižuje zpoždění o 30–70% pro opakované požadavky na stejný host.
Ukládání odpovědí do mezipaměti je implementováno pomocí třídy Cache. Pro zapnutí mezipaměti stačí zadat adresář a maximální velikost v OkHttpClient.Builder. OkHttp automaticky ukládá do mezipaměti GET odpovědi podle hlaviček Cache-Control, Expires a ETag a vrací data z mezipaměti bez síťového požadavku, pokud nejsou zastaralá.
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()
Správná konfigurace poolu a mezipaměti je obzvláště důležitá pro aplikace s častými požadavky — zpravodajské kanály, chaty, aktualizace dat. Bez poolu vyžaduje každé TCP spojení třícestný handshake (SYN, SYN-ACK, ACK) a potenciálně TLS handshake (2–3 round-trip), což přidává 100–500 ms ke každému požadavku.
OkHttp také podporuje WebSocket prostřednictvím třídy RealWebSocket. WebSocket spojení je navázáno přes HTTP handshake (101 Switching Protocols) a poté přechází na obousměrný protokol. OkHttp automaticky odesílá ping rámce pro udržení spojení při životě a znovu se připojuje při přerušení. WebSocket od OkHttp je kompatibilní se standardními endpointy jako wss://echo.websocket.org.
Vytváření OkHttpClient pro každý požadavek — nejčastější chyba. OkHttpClient obsahuje pool spojení, mezipaměť a pool vláken. Vytváření nové instance pro každý požadavek nejen plýtvá pamětí, ale také zbavuje výhody opětovného použití spojení. OkHttpClient by měl být singleton přes DI kontejner.
Ignorování zavírání Response.body() vede k úniku zdrojů. ResponseBody obsahuje InputStream, který musí být po přečtení uzavřen. Pokud se používá body().string() nebo body().bytes(), OkHttp zavírá proud automaticky, ale při čtení body().byteStream() nebo body().charStream() je vyžadováno explicitní zavolání close() v bloku finally.
Chybějící zpracování Timeoutu — další problém. Ve výchozím nastavení OkHttp nemá časové limity (connectTimeout = 10 sekund, readTimeout = 10 sekund, writeTimeout = 10 sekund). Pro mobilní aplikace s nestabilním spojením se doporučuje nastavit connectTimeout 15–30 sekund a readTimeout 15–30 sekund, jinak bude uživatel při slabém signálu čekat příliš dlouho.
Často kladené otázky
OkHttp je nízkoúrovňový HTTP klient s ručním řízením Request a Response. Retrofit je vysokoúrovňový obal s anotacemi. OkHttp se používá jako transport pro Retrofit, ale může pracovat i samostatně bez dalších knihoven.
OkHttp používá SSLSocketFactory pro TLS handshake. Knihovna podporuje CertificatePinner pro připnutí certifikátů (Certificate Pinning), TrustManager pro vlastní validaci a HostnameVerifier pro kontrolu názvu hostitele proti certifikátu.
Synchrónní požadavky vyhazují IOException při problémech se sítí. Asynchronní požadavky obdrží volání onFailure s IOException. Pro HTTP chyby (4xx, 5xx) je odpověď považována za úspěšnou — kód chyby se kontroluje pomocí response.isSuccessful().
Ano, OkHttp má vestavěnou podporu pro WebSocket přes třídu WebSocket a WebSocketListener. Po navázání spojení umožňuje WebSocket odesílat a přijímat zprávy v reálném čase bez opakovaných HTTP požadavků.
Vypněte automatická přesměrování pomocí followRedirects(false) a followSslRedirects(false) v OkHttpClient.Builder. To je užitečné, když potřebujete ručně zpracovat přesměrování, například pro extrakci tokenu z URL přesměrování.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také