基本使用方式
创建Request
Request request = new Request.Builder().url().get().build();
创建OkHttpClient
OkHttpClient client = new OkHttpClient();
public final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor())
.cache(new Cache(cacheDir, cacheSize))
.build();
OkHttpClient client = client.newBuilder()
.readTimeout(500, TimeUnit.MILLISECONDS)
.build();
执行
Response response = client.newCall(request).execute();
client.newCall(request).enqueue(callback);
清理
client.dispatcher().executorService().shutdown();
client.connectionPool().evictAll();
client.cache().close();
代码流程分析
创建RealCall
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
如果是同步的call
直接调用RealCall.execute
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.timeoutEnter();
transmitter.callStart();
try {
client.dispatcher().executed(this);
return getResponseWithInterceptorChain();
} finally {
client.dispatcher().finished(this);
}
}
如若调用enqueue方法,就会走到AsyncCall
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.callStart();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
AsyncCall是Runnalbe 包装了callback
client.dispatcher().enqueue调用了promoteAndExecute
private boolean promoteAndExecute() {
assert (!Thread.holdsLock(this));
List<AsyncCall> executableCalls = new ArrayList<>();
boolean isRunning;
synchronized (this) {
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall asyncCall = i.next();
if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.
i.remove();
asyncCall.callsPerHost().incrementAndGet();
executableCalls.add(asyncCall);
runningAsyncCalls.add(asyncCall);
}
isRunning = runningCallsCount() > 0;
}
for (int i = 0, size = executableCalls.size(); i < size; i++) {
AsyncCall asyncCall = executableCalls.get(i);
asyncCall.executeOn(executorService());
}
return isRunning;
}
asyncCall.executeOn(executorService());
/**
* Attempt to enqueue this async call on {@code executorService}. This will attempt to clean up
* if the executor has been shut down by reporting the call as failed.
*/
void executeOn(ExecutorService executorService) {
assert (!Thread.holdsLock(client.dispatcher()));
boolean success = false;
try {
executorService.execute(this);
success = true;
} catch (RejectedExecutionException e) {
InterruptedIOException ioException = new InterruptedIOException("executor rejected");
ioException.initCause(e);
transmitter.noMoreExchanges(ioException);
responseCallback.onFailure(RealCall.this, ioException);
} finally {
if (!success) {
client.dispatcher().finished(this); // This call is no longer running!
}
}
}
下面执行到了execute,调用 Response response = getResponseWithInterceptorChain();
@Override protected void execute() {
boolean signalledCallback = false;
transmitter.timeoutEnter();
try {
Response response = getResponseWithInterceptorChain();
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
responseCallback.onFailure(RealCall.this, e);
}
} catch (Throwable t) {
cancel();
if (!signalledCallback) {
IOException canceledException = new IOException("canceled due to " + t);
canceledException.addSuppressed(t);
responseCallback.onFailure(RealCall.this, canceledException);
}
throw t;
} finally {
client.dispatcher().finished(this);
}
}
getResponseWithInterceptorChain()
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(new RetryAndFollowUpInterceptor(client));
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
originalRequest, this, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
boolean calledNoMoreExchanges = false;
try {
Response response = chain.proceed(originalRequest);
if (transmitter.isCanceled()) {
closeQuietly(response);
throw new IOException("Canceled");
}
return response;
} catch (IOException e) {
calledNoMoreExchanges = true;
throw transmitter.noMoreExchanges(e);
} finally {
if (!calledNoMoreExchanges) {
transmitter.noMoreExchanges(null);
}
}
}
RealInterceptorChain.proceed
public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)
throws IOException {
Response response = interceptor.intercept(next);
}
接下来走到Interceptor.intercept
RealCall.getResponseWithInterceptorChain 可以看到有四个
interceptors.add(new RetryAndFollowUpInterceptor(client));
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
CallServerInterceptor
RetryAndFollowUpInterceptor 处理3XX重定向的,4XX授权,5xx服务器错误retry等
Location
@Override public Response intercept(Chain chain)
Request followUp = followUpRequest(response, route);
case HTTP_MULT_CHOICE:
case HTTP_MOVED_PERM:
case HTTP_MOVED_TEMP:
case HTTP_SEE_OTHER:
// Does the client allow redirects?
if (!client.followRedirects()) return null;
String location = userResponse.header("Location");
BridgeInterceptor
添加了很多header,并且加入了gzip
CacheInterceptor 处理cache
ConnectInterceptor 创建Exechange,建立连接
CallServerInterceptor 调用
exchange.writeRequestHeaders(request);
if (responseBuilder == null) {
responseBuilder = exchange.readResponseHeaders(false);
}
Response response = responseBuilder
.request(request)
.handshake(exchange.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
题外话:
ConnectionPool
最大5个链接,最长 5分钟
实现是RealConnectionPool
Http1.0 很明显无法复用socket链接。
Http2.0 可以复用socket链接
分享到:
相关推荐
赠送jar包:okhttp-3.14.9.jar; 赠送原API文档:okhttp-3.14.9-javadoc.jar; 赠送源代码:okhttp-3.14.9-sources.jar; 赠送Maven依赖信息文件:okhttp-3.14.9.pom; 包含翻译后的API文档:okhttp-3.14.9-javadoc-...
赠送jar包:okhttp-3.14.9.jar; 赠送原API文档:okhttp-3.14.9-javadoc.jar; 赠送源代码:okhttp-3.14.9-sources.jar; 赠送Maven依赖信息文件:okhttp-3.14.9.pom; 包含翻译后的API文档:okhttp-3.14.9-javadoc-...
标题 "okhttp-3.14.9+okio-1.17.2+kotlin-stdlib-1.3.72" 提供了关于这个压缩包内容的关键信息,它包含的是三个重要的库:OkHttp 3.14.9 版本、Okio 1.17.2 版本以及 Kotlin 标准库 1.3.72 版本。这些库在Java和...
**OkHttp 网络框架详解** OkHttp 是一个高效的、免费开源的网络通信库,由 Square 公司开发并维护。它以其简洁的 API 设计、强大的性能和丰富的特性在 Android 开发者中广受欢迎。OkHttp 的目标是简化网络请求的...
okhttp网络通信包,okhttp3jar包是一款可以支持android网络框架之OKhttp的jar包,一个处理网络请求的开源项目,是目前android安卓端最火热的轻量级框架。
分享okhttp-3.14.1.jar下载,官方下载地址:https://square.github.io/okhttp/#download,目前官方已经是最新版本,不提供该版本jar下载。
本篇将详细讲解如何使用OkHttp进行网络访问,并解析返回的JSON与XML数据。 首先,我们需要了解OkHttp的基本用法。OkHttp是一个异步的HTTP客户端,它通过减少网络延迟和内存使用来提高性能。创建一个OkHttpClient...
**Android OkHttp框架解析** OkHttp是Square公司推出的一个高效的HTTP客户端库,广泛应用于Android开发中,因其优秀的性能和简洁的API设计而受到开发者们的喜爱。OkHttp通过使用连接池、HTTP/2协议以及对现代网络...
OkHttp旨在通过减少网络延迟和减少内存使用来提高应用程序的性能。这个版本的发布可能包含了性能优化、新功能、bug修复或对先前版本的改进。 描述中提到的"okio-1.6.0.jar"是OkHttp依赖的一个重要库,Okio是一个...
【Android OkHttp完全解析】 OkHttp是Square公司开发的一个高效的HTTP客户端库,广泛应用于Android开发中,用于处理网络请求。由于其性能优异、易于使用,它逐渐替代了Android原生的HttpClient。本文将全面解析...
javaweb常用jar包,javaee框架常用jar包,亲测可用,若需其他版本可给我留言
注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...
**OkHttp3源码解析** OkHttp3是Android平台上的一个高效、易用的网络通信库,由Square公司开发。它的出现解决了Android原生HttpURLConnection的性能问题,提供了更强大的功能和更好的网络请求管理。本解析主要围绕...
官方完整版okhttp3 maven <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp (insert latest version) </dependency>
OkHttp-3.12.8.jar 是 OkHttp 库的一个特定版本,包含了所有必要的类和资源文件,用于集成到 Java 项目中。这个版本发布于较早的时间,可能不包含最新特性或安全更新,但依然被许多项目所使用。如果你的新项目需要...
本示例将探讨如何利用OkHttp进行网络请求,并结合JSON解析来创建一个简单的网络请求工具。下面我们将详细介绍这个过程。 首先,我们需要了解OkHttp的基本用法。OkHttp是一个异步HTTP客户端,它通过连接池和协议协商...
在服务器端,你需要根据接收到的数据类型进行相应的解析,例如,如果是JSON格式,可以使用JSON解析库(如Jackson或Gson)进行解析;如果是表单数据,可以使用`request.getParameter()`方法获取参数。 5. **OkHttp...
《鸿洋大神的OkHttp源码解析及应用》 OkHttp是Android平台上广泛使用的网络请求库,由Square公司开发,以其高效、易用著称。鸿洋大神的OkHttp源码解析提供了深入理解这一工具的机会,让我们能够更好地利用其功能并...