Unser Hintergrund: Wir sind Geonode und verkaufen Proxys, und die Proxy-Konfiguration von OkHttp ist wirklich ungewöhnlich – die Proxy-Authentifizierung erfolgt über einen proxyAuthenticator und nicht über einen Header, und wenn man hier einen Fehler macht, wird ein 407-Fehler ausgegeben, der wie ein Problem mit den Anmeldedaten aussieht, obwohl es sich um ein Konfigurationsproblem handelt. Dieser Abschnitt befindet sich gegen Ende. Alles davor funktioniert ganz ohne Proxy, und wenn Sie sich mit der Bibliothek vertraut machen möchten, sollten Sie dies zunächst mit Ihrer eigenen Verbindung tun.
Wo sich OkHttp jetzt befindet
Das sollte gleich zu Beginn erwähnt werden, da die alten Links nicht mehr funktionieren.
Das Repository von OkHttp wurde verschoben. github.com/square/okhttp
leitet nun zu github.com/lysine-dev/okhttp
weiter, und die Dokumentationsseite, die sich zuvor unter square.github.io/okhttp
befand, gibt einen 404-Fehler zurück – die aktuelle Seite ist unter lysine.dev/okhttp
zu finden. Das Projekt wird aktiv gepflegt und steht unter der Apache-2.0-Lizenz, wie im September 2026 überprüft wurde.
Die Maven-Koordinaten haben sich nicht geändert. Es wird weiterhin als com.squareup.okhttp3:okhttp
veröffentlicht:
implementation("com.squareup.okhttp3:okhttp:5.5.0")
Es gibt außerdem eine Stückliste, um die zugehörigen Artefakte auf dem neuesten Stand zu halten:
implementation(platform("com.squareup.okhttp3:okhttp-bom:5.5.0"))
Anforderungen: Android 5.0+ (API-Level 21+) und Java 8+. OkHttp ist für die Ein- und Ausgabe auf Okio sowie auf die Kotlin-Standardbibliothek angewiesen – beides wird vom Projekt als „kleine Bibliotheken mit starker Abwärtskompatibilität“ beschrieben. Unter Android wird AndroidX Startup verwendet. Wenn Sie den Initialisierer im Manifest deaktivieren, muss Ihre App die Methode „OkHttp.initialize(applicationContext)
“ in „Application.onCreate
“ aufrufen.
Der alte Zweig „3.12.x
“ unterstützt Android 2.3+ und Java 7, wobei das Projekt unmissverständlich darauf hinweist, dass diese Plattformen „keine Unterstützung für TLS 1.2 bieten und nicht verwendet werden sollten“.
Ihre erste Anfrage
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
In diesem siebenzeiligen Beispiel sind drei Dinge von Bedeutung.
** „try
-with-resources“ ist nicht optional.** „Response
“ implementiert „Closeable
“, und eine nicht geschlossene Antwort hält ihre Verbindung aufrecht. Bei ausreichenden Leckagen wird der Pool aufgebraucht; ab diesem Zeitpunkt hängen Anfragen, anstatt fehlzuschlagen – ein Symptom, das wie ein Netzwerkproblem aussieht, aber keines ist.
**body().string()
darf nur einmal aufgerufen werden.** Die Funktion verbraucht den Stream. Ein zweiter Aufruf löst einen Fehler aus, ebenso wie ein Aufruf nach dem Schließen der Antwort. Wenn Sie den Body mehr als einmal benötigen, speichern Sie die Zeichenkette.
** ``execute()`
ist synchron.** Für asynchrone Vorgänge verwendet ``enqueue()
einen ``Callback
` und wird im Dispatcher-Thread-Pool von OkHttp ausgeführt.
Ein POST-Request hat dieselbe Struktur mit einem Body:
public static final MediaType JSON = MediaType.get("application/json");
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
Den Client gemeinsam nutzen
Die Entwurfsentscheidung, bei der die meisten Fehler gemacht werden.
OkHttpClient
verwaltet einen Verbindungspool und einen Thread-Pool. Wenn Sie pro Anfrage einen neuen Client erstellen, werden alle Verbindungen, die Sie möglicherweise wiederverwendet hätten, verworfen, und es werden Threads erstellt, die Sie anschließend nicht mehr nutzen. Das funktioniert zwar, ist aber langsam und verbraucht unter Last die Ressourcen.
Erstellen Sie einen Client für Ihre Anwendung und nutzen Sie ihn gemeinsam. Er ist von Haus aus threadsicher.
Wenn Sie für einen Teil Ihres Codes andere Einstellungen benötigen, erstellen Sie keinen zweiten Client von Grund auf neu – klonen Sie den bestehenden, damit die Pools gemeinsam genutzt werden:
OkHttpClient shortTimeout = client.newBuilder()
.readTimeout(5, TimeUnit.SECONDS)
.build();
newBuilder()
erzeugt einen Client, der den Verbindungspool und den Dispatcher mit seinem übergeordneten Client teilt, was genau dem entspricht, was Sie wollen.
Geben Sie beim Herunterfahren, insbesondere bei kurzlebigen Prozessen, die Ressourcen explizit frei:
client.dispatcher().executorService().shutdown();
client.connectionPool().evictAll();
Ohne diese Maßnahme kann sich eine JVM für die Dauer des Keep-Alive des Pools aufhängen, bevor sie beendet wird, was bei der Fehlersuche in einem CLI-Tool sehr verwirrend sein kann.
Was OkHttp Ihrer Anfrage hinzufügt
Die Bibliothek schreibt Anfragen um, und wenn Sie wissen, was sie hinzufügt, lassen sich gewisse Unklarheiten vermeiden.
Die Dokumentation ist eindeutig: „OkHttp fügt möglicherweise Header hinzu, die in der ursprünglichen Anfrage fehlen, darunter Content-Length, Transfer-Encoding, User-Agent, Host, Connection und Content-Type. Es fügt einen Accept-Encoding-Header für transparente Antwortkomprimierung hinzu, sofern dieser Header nicht bereits vorhanden ist. Wenn Sie Cookies haben, fügt OkHttp einen Cookie-Header mit diesen hinzu.“
Daraus ergeben sich zwei Konsequenzen.
Die transparente Komprimierung erfolgt automatisch und wird für Sie rückgängig gemacht. OkHttp fordert die Komprimierung an, dekomprimiert die Antwort und „entfernt anschließend die entsprechenden Antwort-Header Content-Encoding und Content-Length, da diese für den dekomprimierten Antworttext nicht gelten“. Ein fehlender „Content-Length“-Header in einer Antwort ist also eher normal als ein Fehler – es sei denn, Sie legen „Accept-Encoding“ selbst fest; in diesem Fall sind Sie für die Dekomprimierung verantwortlich.
Bedingte Anfragen erfolgen automatisch, wenn das Caching aktiviert ist. OkHttp fügt If-Modified-Since und If-None-Match hinzu, um veraltete Cache-Einträge erneut zu validieren.
Außerdem folgt es standardmäßig Weiterleitungen und „fordert bei einer Autorisierungsanfrage den Authenticator (sofern konfiguriert) auf, die Anforderung zu erfüllen“, wobei es es mit den bereitgestellten Anmeldedaten erneut versucht.
Die Bibliothek beschreibt sich selbst als „prinzipientreu und vermeidet es, übermäßig konfigurierbar zu sein, insbesondere wenn eine solche Konfiguration dazu dient, einen fehlerhaften Server zu umgehen, ungültige Szenarien zu testen oder solche, die dem entsprechenden RFC widersprechen“. Sie nennt ihre eigenen Einschränkungen offen – sie „erlaubt keine GET-Anfragen mit einem Body“, und der Cache „ist keine Schnittstelle mit alternativen Implementierungen“. Wenn Sie absichtlich ungültige Anfragen senden müssen, ist dies nicht die richtige Bibliothek dafür, und das ist eine bewusste Designentscheidung und kein Versehen.
Interceptoren
Der wichtigste Erweiterungspunkt und das einzige Feature, das die Art und Weise prägt, wie Sie die Bibliothek nutzen.
class LoggingInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
}
In der Dokumentation wird ausdrücklich betont: „Ein Aufruf von chain.proceed(request) ist ein entscheidender Bestandteil der Implementierung jedes Interceptors. In dieser auf den ersten Blick einfach aussehenden Methode findet die gesamte HTTP-Verarbeitung statt.“ Und eine Warnung, die es zu beachten gilt: „Wenn chain.proceed(request) mehr als einmal aufgerufen wird, müssen vorherige Antwortkörper geschlossen werden.“
Es gibt zwei Arten, und die richtige Wahl ist entscheidend. Registrieren Sie sich mit addInterceptor() oder addNetworkInterceptor(). Die Dokumentation erläutert den Unterschied genau.
Anwendungs-Interceptors:
- „Man muss sich keine Gedanken über Zwischenantworten wie Weiterleitungen und Wiederholungsversuche machen.“
- „Werden immer einmal aufgerufen, auch wenn die HTTP-Antwort aus dem Cache bereitgestellt wird.“
- „Beachten die ursprüngliche Absicht der Anwendung. Sie berücksichtigen keine von OkHttp eingefügten Header wie
If-None-Match.“ - „Dürfen den Aufruf abbrechen und
Chain.proceed()nicht aufrufen.“ - „Dürfen Wiederholungsversuche durchführen und mehrere Aufrufe an
Chain.proceed()senden.“ - „Die Zeitlimits für Aufrufe können über
withConnectTimeout,withReadTimeoutundwithWriteTimeoutangepasst werden.“
Netzwerk-Interceptoren:
- „Können auf Zwischenantworten wie Weiterleitungen und Wiederholungsversuche einwirken.“
- „Werden nicht für zwischengespeicherte Antworten aufgerufen, die den Netzwerkzugriff umgehen.“
- „Beobachten Sie die Daten genau so, wie sie über das Netzwerk übertragen werden.“
- „Zugriff auf den
Connection, der die Anfrage transportiert.“
Die praktische Regel: Verwenden Sie einen Anwendungs-Interceptor für alles, was mit der Absicht Ihrer Anfrage zu tun hat – Hinzufügen eines Autorisierungs-Headers, eines User-Agents, Protokollierung auf Anwendungsebene. Verwenden Sie einen Netzwerk-Interceptor für alles, was tatsächlich über das Netzwerk übertragen wird – zum Überprüfen komprimierter Body-Inhalte, zum Anzeigen jedes Umleitungsschritts und zum Untersuchen der Verbindung.
Der häufigste Fehler besteht darin, einen Authentifizierungs-Interceptor als Netzwerk-Interceptor zu registrieren, der dann bei jedem Umleitungsschritt ausgelöst wird und Ihre Anmeldedaten an einen Host weitergeben kann, den Sie nicht beabsichtigt haben.
Timeouts
OkHttp verfügt über sinnvolle Standardeinstellungen und vier separate Einstellungen. Wenn Sie wissen, welche davon ausgelöst wurde, können Sie erkennen, wo das Problem liegt.
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.callTimeout(60, TimeUnit.SECONDS)
.build();
**connectTimeout
** behandelt den Aufbau der TCP- und TLS-Verbindung.
**readTimeout
** gilt für einzelne Lesevorgänge, nicht für die gesamte Antwort – ein langsamer, aber fortschreitender Download löst diesen Timeout also nie aus.
**writeTimeout
** funktioniert genauso bei Uploads.
**callTimeout
** begrenzt den gesamten Aufruf einschließlich Weiterleitungen, Wiederholungsversuchen und der Übertragung des Hauptteils. Der Standardwert ist Null, was bedeutet, dass es keine Gesamtbegrenzung gibt.
Letzteres ist die Einstellung, die du festlegen solltest. Ohne diese Einstellung kann ein Aufruf, bei dem Daten nur tröpfchenweise eingehen, unbegrenzt lange laufen, da das Lese-Timeout bei jedem empfangenen Byte zurückgesetzt wird. „callTimeout
“ ist die Obergrenze, die einen Job beendet, und entspricht dem „--max-time
“ in curl – einen Unterschied, den wir in „Ein Timeout mit curl festlegen“ erläutert haben.
Überschreibungen pro Aufruf sind über die Methoden „withReadTimeout
“ und ähnliche Funktionen eines Anwendungs-Interceptors möglich. Auf diese Weise können Sie einem langsamen Endpunkt mehr Spielraum geben, ohne die Standardeinstellungen für alle anderen Aufrufe zu lockern.
Proxys
Hier unterscheidet sich OkHttp von den meisten Clients – und hier verlieren viele Nutzer Zeit.
Proxy proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("proxy.example.com", 9000));
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.build();
Für SOCKS verwenden Sie Proxy.Type.SOCKS mit dem gleichen Aufbau.
Die Authentifizierung ist der Teil, der viele Nutzer überrascht. Sie setzen keinen „Proxy-Authorization“-Header. Sie übergeben eine proxyAuthenticator, die OkHttp aufruft, wenn der Proxy eine 407-Anfrage stellt:
Authenticator proxyAuth = (route, response) -> {
if (response.request().header("Proxy-Authorization") != null) {
return null; // already tried these credentials; give up
}
String credential = Credentials.basic("user", "pass");
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
};
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuth)
.build();
Die Rückgabe von null ist unerlässlich. Ohne sie führt ein falsches Passwort zu einer endlosen Wiederholungsschleife statt zu einem Fehler – OkHttp fragt den Authentifikator ab, erhält dieselben falschen Anmeldedaten, erhält erneut einen 407-Fehler und fragt erneut. Indem Sie prüfen, ob Sie bereits einen „Proxy-Authorization“-Header gesendet haben, können Sie diesen Kreislauf durchbrechen.
Drei weitere Anmerkungen.
Ein 407-Fehler ist kein 401-Fehler. Der Proxy hat Sie abgelehnt und das Ziel wurde nie erreicht. Ein 401-Fehler bedeutet, dass der Proxy funktioniert hat und das Ziel Anmeldeinformationen verlangt – was eine völlig andere „authenticator()“-Einstellung ist.
Mit „proxySelector()“ können Sie einen Proxy pro Anfrage statt pro Client auswählen. Auf diese Weise leiten Sie verschiedene Hosts unterschiedlich weiter, ohne mehrere Clients erstellen zu müssen.
Überprüfen Sie, ob die Änderung wirksam wurde. Rufen Sie einen Dienst auf, der Ihre Adresse zurückgibt – sowohl mit als auch ohne konfigurierten Proxy. Eine Fehlkonfiguration bleibt hier unbemerkt – Anfragen sind erfolgreich und werden direkt weitergeleitet –, und die Überprüfung der Ausgangsadresse ist die einzige Möglichkeit, sich zu vergewissern. Über dieses Muster des „stillen Erfolgs“ haben wir in Warum das Testen von Proxys wichtig ist geschrieben.
Korrekter Umgang mit Antworten
Einige Muster, die den Unterschied zwischen Code, der funktioniert, und Code, der auch unter Last funktioniert, ausmachen.
**Prüfen Sie „isSuccessful()
“, nicht nur das Fehlen einer Ausnahme.** OkHttp löst bei Netzwerkfehlern eine „IOException
“ aus, nicht bei HTTP-Fehlerstatus. Ein 404- oder 500-Fehler wird als gewöhnliche „Response
“ zurückgegeben:
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
String body = response.body() != null ? response.body().string() : "";
throw new IOException("HTTP " + response.code() + " from " + request.url()
+ ": " + body.substring(0, Math.min(200, body.length())));
}
return response.body().string();
}
Durch Einfügen des ersten Teils des Fehlertextes wird aus einem undurchsichtigen Statuscode eine Meldung, die das Problem benennt – die meisten APIs erklären sich selbst im Textkörper eines 400-Fehlers.
Puffern Sie große Antworten nicht in einem String. „body().string()
“ liest alles in den Arbeitsspeicher ein. Bei einem großen Download sollten Sie diesen per Stream übertragen:
try (Response response = client.newCall(request).execute();
BufferedSource source = response.body().source();
BufferedSink sink = Okio.buffer(Okio.sink(new File("out.bin")))) {
sink.writeAll(source);
}
Auch bei asynchronen Aufrufen muss der Textkörper geschlossen werden, und der Callback läuft in einem Hintergrund-Thread:
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
logger.warn("request failed", e);
}
@Override public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody body = response.body()) {
handle(body.string());
}
}
});
Beachten Sie, dass onFailure
ausschließlich bei Netzwerkproblemen ausgelöst wird. Ein HTTP-500-Fehler wird unter onResponse
zurückgegeben, was Nutzer überrascht, die erwarten, dass die Bezeichnung das bedeutet, wonach sie klingt.
Wiederholungsversuche erfordern Sorgfalt. OkHttp wiederholt einige Fehler auf Verbindungsebene automatisch, gesteuert durch retryOnConnectionFailure()
, das standardmäßig aktiviert ist. HTTP-Fehlerstatus werden nicht wiederholt, und das sollte auch nicht geschehen – die Wiederholung eines POST-Aufrufs, der möglicherweise bereits erfolgreich war, kann zu doppelten Schreibvorgängen führen. Wenn Sie eine eigene Wiederholungslogik hinzufügen, tun Sie dies in einem Anwendungs-Interceptor, begrenzen Sie die Anzahl der Versuche, halten Sie zwischen den Versuchen eine Pause ein und beschränken Sie sich auf idempotente Methoden, es sei denn, die API bietet einen Idempotenzschlüssel an.
Was es Ihnen sonst noch bietet
Kurz gesagt, denn das sind die Gründe, sich dafür zu entscheiden.
HTTP/2, wobei „die Unterstützung es ermöglicht, dass alle Anfragen an denselben Host einen gemeinsamen Socket nutzen“. Verbindungspooling, das „die Latenz bei Anfragen reduziert (sofern HTTP/2 nicht verfügbar ist)“. Transparentes GZIP. Antwort-Caching, das „bei wiederholten Anfragen den Umweg über das Netzwerk vollständig vermeidet“.
Ausfallsicherheit. Es „behebt gängige Verbindungsprobleme im Hintergrund“, und wenn ein Dienst über mehrere Adressen verfügt, „versucht es es mit alternativen Adressen, falls die erste Verbindung fehlschlägt“ – was laut Projektangaben „für IPv4+IPv6 und Dienste, die in redundanten Rechenzentren gehostet werden, notwendig ist“.
Modernes TLS, einschließlich TLS 1.3, ALPN und Certificate Pinning, unter Verwendung der Plattformimplementierung. Auf der JVM unterstützt es zudem Conscrypt, das BoringSSL in Java integriert und automatisch verwendet wird, sofern es der erste Sicherheitsanbieter ist.
Einhaltung von Standards. Das Projekt listet die Spezifikationen auf, denen es folgt: RFC 9110 für HTTP-Semantik, RFC 9111 für Caching, RFC 9112 für HTTP/1.1, RFC 9113 für HTTP/2, RFC 6455 für WebSockets und die WHATWG-Spezifikation für Server-Sent Events. Ist eine Spezifikation mehrdeutig, „orientiert es sich an modernen User Agents wie gängigen Browsern oder verbreiteten HTTP-Bibliotheken“.
Häufig gestellte Fragen
Wird OkHttp noch weiterentwickelt?
Ja. Das Repository wurde von square/okhttp auf lysine-dev/okhttp verlegt und die Dokumentationsseite befindet sich nun unter lysine.dev/okhttp, aber das Projekt wird aktiv weiterentwickelt und steht unter der Apache-2.0-Lizenz. Die Maven-Koordinaten lauten weiterhin com.squareup.okhttp3:okhttp.
Sollte ich für jede Anfrage einen neuen OkHttpClient erstellen?
Nein. Der Client verfügt über einen Verbindungspool und einen Thread-Pool und ist von Grund auf threadsicher. Erstellen Sie einen für Ihre Anwendung und nutzen Sie ihn gemeinsam. Wenn Sie andere Einstellungen benötigen, verwenden Sie „newBuilder()“ für den bestehenden Client, damit die Pools gemeinsam genutzt werden.
Warum muss ich die Antwort schließen?
Weil Response eine Verbindung so lange aufrechterhält, bis sie geschlossen wird, und nicht geschlossene Antworten den Verbindungspool erschöpfen. Das Symptom sind Anfragen, die hängen bleiben, anstatt fehlzuschlagen, was schwer zu diagnostizieren ist. Verwenden Sie immer try-with-resources.
Was ist der Unterschied zwischen einem Anwendungs- und einem Netzwerk-Interceptor?
Ein Anwendungs-Interceptor sieht Ihre ursprüngliche Anfrage und wird genau einmal aufgerufen – auch bei zwischengespeicherten Antworten – und kann den Vorgang abbrechen oder einen erneuten Versuch starten. Ein Netzwerk-Interceptor sieht jeden einzelnen Netzwerkaustausch einschließlich Weiterleitungen und Wiederholungsversuchen, hat Zugriff auf die Verbindung und wird bei zwischengespeicherten Antworten vollständig übersprungen.
Wie richte ich einen Proxy in OkHttp ein?
Übergeben Sie einen „java.net.Proxy“ an „OkHttpClient.Builder.proxy()“. Für die Authentifizierung sollten Sie einen „proxyAuthenticator“ anstelle eines Headers verwenden – und „null“ zurückgeben, wenn bereits ein „Proxy-Authorization“-Header vorhanden ist, da falsche Anmeldedaten sonst zu einer endlosen Wiederholungsschleife führen.
Welche Timeouts sollte ich festlegen?
„connectTimeout“ auf etwa 10 Sekunden, „readTimeout“ und „writeTimeout“ auf etwa 30 Sekunden und – am wichtigsten – „callTimeout“, das standardmäßig auf Null gesetzt ist und die einzige Einstellung darstellt, die den gesamten Aufruf begrenzt. Ohne diese Einstellung läuft eine langsam eintreffende Antwort niemals ab, da das Lese-Timeout bei jedem Byte zurückgesetzt wird.
Unterstützt OkHttp GZIP automatisch?
Ja, sofern Sie „Accept-Encoding“ nicht selbst festlegen. OkHttp fordert die Komprimierung an, dekomprimiert die Antwort und entfernt „Content-Encoding“ sowie „Content-Length“, da diese nicht mehr den dekomprimierten Body beschreiben. Wenn Sie den Header manuell festlegen, übernehmen Sie auch die Dekomprimierung.
Welche Java-Version benötigt OkHttp?
Java 8 oder höher sowie Android 5.0 (API-Level 21) oder höher. OkHttp ist auf Okio und die Kotlin-Standardbibliothek angewiesen. Der alte 3.12.x-Zweig unterstützt zwar Java 7 und Android 2.3, bietet jedoch keine TLS-1.2-Unterstützung und sollte daher nicht verwendet werden.
Zusammenfassung
OkHttp ist eine kleine API, die auf einer gut durchdachten Implementierung basiert, und zwei Vorgehensweisen decken den Großteil der korrekten Nutzung ab: Verwenden Sie einen einzigen Client für Ihre gesamte Anwendung und schließen Sie jede Antwort mit ``try-with-resources ab. Beide Fehler verlaufen still und äußern sich letztendlich eher in hängenden Anfragen als in lesbaren Fehlermeldungen.
Interceptors sind der Bereich, mit dem Sie sich am meisten beschäftigen werden, und es lohnt sich, den Unterschied zwischen Anwendungs- und Netzwerk-Interceptors gründlich zu lernen, anstatt ihn durch Ausprobieren zu ergründen. Anwendungs-Interceptors erkennen Ihre Absicht und werden einmal ausgeführt; Netzwerk-Interceptors erkennen jeden Schritt und werden bei zwischengespeicherten Antworten übersprungen. Die Registrierung eines Autorisierungs-Interceptors auf der Netzwerkebene ist der klassische Fehler, und er wird bei jeder Weiterleitung ausgelöst.
Lege eine „callTimeout“ fest. Der Standardwert ist Null; dies ist die einzige Einstellung, die einen gesamten Aufruf begrenzt, und ihr Fehlen ist der Grund dafür, dass ein Job, der eigentlich nur Sekunden dauern sollte, gelegentlich so lange läuft, bis etwas anderes ihn beendet.
Und falls du dich an ältere Dokumentationen hältst, überprüfe die Links. Das Projekt ist auf lysine.dev/okhttp umgezogen, und die von Square gehostete Seite existiert nicht mehr – die Artefakt-Koordinaten sind jedoch unverändert, sodass deine Build-Datei keine Anpassungen benötigt.
