Rxjava:
https://www.jianshu.com/p/7474950af2df
基本使用方式
创建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链接
分享到:
相关推荐
okhttp请求+FastJson解析数据
WebView布局使用,okHTTP访问解析服务器返回的json/xml数据。
SpringBoot OkHttp3,里面包含了各种测试代码,其中包含了get,post,文件上传等测试
简单封装OKhttp Retrofit Rxjava代码,支持参数加密解密,按需选择库,支持日志库按需选择,支持主动取消请求,支持json,表单请求,暂只支持get,post请求方式两种,支持单点登录,一行代码发起请求
okhttp学习简单示例代码,附带后端server源码下载
赠送源代码:okhttp-2.7.1-sources.jar; 赠送Maven依赖信息文件:okhttp-2.7.1.pom; 包含翻译后的API文档:okhttp-2.7.1-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:...
Android网络请求OkHttp的使用demo代码
高度分装的OkHttp
OKHttp3源码分析,反编译了OKHttp3项目源码,并对源码整体实现添加了详细的注释,方便查看是想流程。
赠送源代码:okhttp-2.4.0-sources.jar; 赠送Maven依赖信息文件:okhttp-2.4.0.pom; 包含翻译后的API文档:okhttp-2.4.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.squareup.okhttp:okhttp:2.4.0; 标签...
赠送源代码:okhttp-3.14.9-sources.jar; 赠送Maven依赖信息文件:okhttp-3.14.9.pom; 包含翻译后的API文档:okhttp-3.14.9-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:...
赠送源代码:okhttp-3.3.1-sources.jar; 包含翻译后的API文档:okhttp-3.3.1-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:com.squareup.okhttp3,artifactId:okhttp,version:3.3.1 使用方法:...
目录前言正文OkHttp使用示例源码解析Apache HttpClient使用示例源码解析GoogleHttpClient哪个更香?总结声明 前言 前八篇文章介绍完了feign-core核心内容,从本篇开始将介绍它的“其它模块”。其实核心模块可以独立...
okhttp3 开源代码
赠送源代码:okhttp-3.11.0-sources.jar; 赠送Maven依赖信息文件:okhttp-3.11.0.pom; 包含翻译后的API文档:okhttp-3.11.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.squareup.okhttp3:okhttp:3.11.0;...
赠送源代码:okhttp-3.14.9-sources.jar; 赠送Maven依赖信息文件:okhttp-3.14.9.pom; 包含翻译后的API文档:okhttp-3.14.9-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.squareup.okhttp3:okhttp:3.14.9;...
OkHttp使用简单代码 加载依赖包 compile 'com.squareup.okhttp3:okhttp:3.10.0' 使用的是官方代码 在DUG中无法查看 RequestBody body = RequestBody.create(JSON, json); 封装的数据。 将之替换成传递键值对参数...
赠送源代码:okhttp-2.7.5-sources.jar; 赠送Maven依赖信息文件:okhttp-2.7.5.pom; 包含翻译后的API文档:okhttp-2.7.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.squareup.okhttp:okhttp:2.7.5; 标签...
Android通过微信实现第三方登录并使用OKHttp获得Token的源码,工程中还包括仿今日头条、知乎等App的顶部滑动菜单,底部菜单实现等代码。
赠送源代码:okhttp-3.8.1-sources.jar; 赠送Maven依赖信息文件:okhttp-3.8.1.pom; 包含翻译后的API文档:okhttp-3.8.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.squareup.okhttp3:okhttp:3.8.1; ...