OkHttp är en högpresterande HTTP-klient för Android och Kotlin, utvecklad av Square som grund för Retrofit och andra nätverksbibliotek. Den ger effektiv anslutningshantering, inbyggd cachning och stöd för HTTP/2. Enligt Square, 2025 behandlar OkHttp miljarder förfrågningar dagligen i applikationer över hela världen.
Huvudpunkter
OkHttp är en effektiv HTTP-klient för Java, Android och Kotlin, utvecklad av Square. Biblioteket tillhandahåller ett lågnivå-API för att utföra HTTP-förfrågningar med stöd för HTTP/2, SPDY, WebSocket och automatisk återställning av anslutningar vid nätverksfel.
OkHttp dök upp 2013 som ett svar på behovet av en pålitlig HTTP-klient som skulle lösa problemen med HttpURLConnection — brist på anslutningspool, svagt stöd för HTTP/2 och obekvämt API. År 2025 används OkHttp på systemnivå i Android API: OkHttp är inbäddat i implementeringen av HttpURLConnection sedan Android 4.4 (API 19).
Enligt Google I/O 2024 behandlar OkHttp över 70% av alla HTTP-förfrågningar i Android-ekosystemet. Detta är möjligt eftersom OkHttp är transportlagret för Retrofit, Apollo GraphQL, Firebase och många andra bibliotek. Utvecklare får OkHtpps funktionalitet automatiskt utan att uttryckligen ansluta det.
Arkitekturen för OkHttp är byggd på en kedja av interceptor (Interceptor chain). Varje förfrågan går genom en sekvens av interceptor som kan modifiera Request, Response eller avbryta utförandet. Denna arkitektur påminner om mönstret Chain of Responsibility och möjliggör flexibel utökning av funktionalitet.
När applikationen skickar en förfrågan utför OkHttp följande steg: löser DNS, väljer en anslutning från poolen (eller skapar en ny), öppnar TLS-handskakning (om HTTPS), skickar HTTP-förfrågan, tar emot svaret och returnerar det till applikationen. RealCall är en intern klass som hanterar hela livscykeln för förfrågan från skapande till slutförande.
OkHttp hanterar automatiskt omdirigeringar (302, 301), upprepar förfrågningar vid nätverksfel (retry), följer keep-alive-protokollet och stöder transparent gzip-komprimering. Utvecklaren behöver inte skriva kod för dessa operationer — OkHttp gör dem automatiskt baserat på serverrubriker.
HTTP/2 gör det möjligt att skicka flera förfrågningar via en enda TCP-anslutning samtidigt, utan blockering (head-of-line blocking, karakteristiskt för HTTP/1.1). OkHttp använder automatiskt HTTP/2 om servern stöder detta protokoll och växlar transparent till HTTP/1.1 vid behov.
Multiplexering av HTTP/2 är särskilt viktigt för mobila applikationer, där fördröjningen för att upprätta en anslutning (TCP + TLS) kan vara 100–300 ms. Istället för 10 på varandra följande anslutningar använder OkHttp en enda, vilket minskar den totala fördröjningen med 40–60% på typiska Android-enheter med instabil anslutning.
Interceptor är ett gränssnitt med en enda metod intercept(Chain) som tar emot Request, utför åtgärder och returnerar Response. Interceptorerna är av två typer: applikationsinterceptorer (läggs till via addInterceptor) och nätverksinterceptorer (addNetworkInterceptor).
Applikationsinterceptorer aktiveras före HTTP-förfrågan bildas — de ser den ursprungliga Request och slutliga Response efter alla transformationer. Nätverksinterceptorer aktiveras på nätverksnivå: de ser förfrågan efter gzip-komprimering, tillägg av Content-Length-rubriker, omdirigeringar och återförsök. Nätverksinterceptorer anropas inte om svaret kommer från cachen.
| Interceptortyp | Lägg till metod | När anropas | Ser cache |
|---|---|---|---|
| Application Interceptor | addInterceptor() | Före och efter förfrågan | Ja |
| Network Interceptor | addNetworkInterceptor() | På nätverksnivå | Nej |
I praktiken löser OkHttp-interceptorer tre huvuduppgifter: autorisering (lägga till Authorization-rubrik), loggning (HttpLoggingInterceptor för felsökning) och återförsök (automatisk upprepning av förfrågan vid nätverksfel). Genom att kombinera flera interceptor kan en fullständig pipeline för förfrågningsbearbetning byggas utan kodduplicering i varje HTTP-anrop i applikationen.
Ordningen för att lägga till interceptor har betydelse: Interceptor som läggs till först utförs först vid inmatning och sist vid utmatning. För NetworkInterceptor bestäms ordningen av nätverksstacken. Rekommenderad ordning: AuthInterceptor (lägger till token), LoggingInterceptor (loggar förfrågan), RetryInterceptor (upprepar vid fel).
För felsökning av nätverksförfrågningar används HttpLoggingInterceptor — en färdig interceptor från Square. Den loggar metoden, URL:en, rubriker och kroppen för förfrågan och svar. Loggningsnivåer: BASIC (metod + URL + kod), HEADERS (med rubriker) och BODY (fullständig förfrågan och svar). BODY är användbart under utveckling, men i produktion inaktiveras det av säkerhets- och prestandaskäl.
Låt oss titta på en grundläggande GET-förfrågan via OkHttp. Först skapas OkHttpClient — ett tungt objekt som skapas en gång och återanvänds. Sedan bildas en Request med URL, och förfrågan utförs synkront via execute eller asynkront via 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())
För asynkron utförande används metoden enqueue, som tar emot en Callback. OkHttp utför förfrågan i en bakgrundstråd och returnerar resultatet i callback på samma tråd. För att växla till Android-huvudtråden, använd Handler eller korutiner.
client.newCall(request).enqueue(object : Callback {
override fun onFailure(
call: Call, e: IOException
) {
println("Förfrågan misslyckades: ${e.message}")
}
override fun onResponse(
call: Call, response: Response
) {
println(response.body()?.string())
}
})
En anpassad Interceptor lägger till en Bearer-token till varje förfrågan. Interceptorn kontrollerar förekomsten av Authorization-rubriken, och om token inte har ställts in än, lägger den till den från lagringen. Vid 401-svar kan interceptorn uppdatera token via 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)
}
}
Anslutningspoolen (ConnectionPool) — den viktigaste optimeringen i OkHttp, som möjliggör återanvändning av TCP-anslutningar för flera förfrågningar. Istället för att skapa en ny socket för varje förfrågan lagrar OkHttp upp till 5 inaktiva anslutningar (som standard) i 5 minuter, vilket minskar fördröjningen med 30–70% för upprepade förfrågningar till samma värd.
Cachning av svar implementeras via klassen Cache. För att aktivera cache räcker det att ange katalogen och maximal storlek i OkHttpClient.Builder. OkHttp cachar automatiskt GET-svar enligt Cache-Control, Expires och ETag-rubriker och returnerar cachad data utan nätverksförfrågan om de inte har upphört att gälla.
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()
Korrekt konfiguration av poolen och cachen är särskilt viktig för applikationer med frekventa förfrågningar — nyhetsflöden, chattar, datauppdateringar. Utan pool kräver varje TCP-anslutning en trevägshandskakning (SYN, SYN-ACK, ACK) och potentiellt TLS-handskakning (2–3 round-trip), vilket lägger till 100–500 ms till varje förfrågan.
OkHttp stöder också WebSocket via klassen RealWebSocket. En WebSocket-anslutning upprättas via en HTTP-handskakning (101 Switching Protocols) och växlar sedan till ett tvåvägsprotokoll. OkHttp skickar automatiskt ping-ramar för att hålla anslutningen vid liv och återansluter vid avbrott. WebSocket från OkHttp är kompatibel med standardändpunkter som wss://echo.websocket.org.
Skapa OkHttpClient för varje förfrågan — det vanligaste misstaget. OkHttpClient innehåller anslutningspoolen, cachen och trådpoolen. Att skapa en ny instans för varje förfrågan slösar inte bara minne utan berövar också fördelen med återanvändning av anslutningar. OkHttpClient bör vara en singleton via en DI-container.
Att ignorera stängning av Response.body() leder till resursläckor. ResponseBody innehåller en InputStream som måste stängas efter läsning. Om body().string() eller body().bytes() används stänger OkHttp strömmen automatiskt, men vid läsning av body().byteStream() eller body().charStream() krävs ett explicit anrop av close() i finally-blocket.
Avsaknad av timeout-hantering — ett annat problem. Som standard har OkHttp inga timeouter (connectTimeout = 10 sekunder, readTimeout = 10 sekunder, writeTimeout = 10 sekunder). För mobila applikationer med instabil anslutning rekommenderas att ställa in connectTimeout 15–30 sekunder och readTimeout 15–30 sekunder, annars kommer användaren att vänta för länge vid svag signal.
Vanliga frågor
OkHttp är en lågnivå HTTP-klient med manuell hantering av Request och Response. Retrofit är ett högnivå omslag med annoteringar. OkHttp används som transport för Retrofit, men kan fungera självständigt utan extra bibliotek.
OkHttp använder SSLSocketFactory för TLS-handskakning. Biblioteket stöder CertificatePinner för certifikatpinnning (Certificate Pinning), TrustManager för anpassad validering och HostnameVerifier för att kontrollera värdnamnet mot certifikatet.
Synkrona förfrågningar kastar IOException vid nätverksproblem. Asynkrona förfrågningar får ett onFailure-anrop med IOException. För HTTP-fel (4xx, 5xx) betraktas svaret som framgångsrikt — felkoden kontrolleras via response.isSuccessful().
Ja, OkHttp har inbyggt stöd för WebSocket via klasserna WebSocket och WebSocketListener. Efter att anslutningen har upprättats möjliggör WebSocket realtidsändning och mottagning av meddelanden utan upprepade HTTP-förfrågningar.
Inaktivera automatiska omdirigeringar via followRedirects(false) och followSslRedirects(false) i OkHttpClient.Builder. Detta är användbart när du manuellt behöver hantera en omdirigering, till exempel för att extrahera en token från omdirigerings-URL:en.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också