Android_OkHttp源码分析
本文由 Luzhuo 编写,转发请保留该信息.
原文: http://blog.csdn.net/Rozol/article/details/72895794
基本使用
// 网络请求客户端,仅需一个即可
OkHttpClient client = new OkHttpClient()
// 构建请求
Request request = new Request.Builder().url(url).build();
// 同步请求
Response response = client.newCall(request).execute();
// 异步请求
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
if(callback != null) callback.onResonse(null);
return;
}
callback.onResonse(response);
}
});
源码分析
- 1: 首先看下Request的构建,
Request request = new Request.Builder().url(url).build()
public final class Request {
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
public Builder url(String url) {
if (url == null) throw new NullPointerException("url == null");
// Silently replace web socket URLs with HTTP URLs.
if (url.regionMatches(true, 0, "ws:", 0, 3)) {
url = "http:" + url.substring(3);
} else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
url = "https:" + url.substring(4);
}
HttpUrl parsed = HttpUrl.parse(url);
if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
return url(parsed);
}
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tag = builder.tag != null ? builder.tag : this;
}
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
}
- **主要是一些请求信息,如请求头,请求类型,请求数据,解析url等操作,主要看点是通过Build方式构建了Request**
- 2.1: 先看下
OkHttpClient client = new OkHttpClient()
,OkHttpClient对象全局仅需要一个就可以了,现在看看里面做了什么?
public OkHttpClient() {
this(new Builder());
}
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
- 可见Builder()里主要做的还是初始化一些信息
2.2: 然后OkHttpClient调用
.newCall(request)
@Override public Call newCall(Request request) { return new RealCall(this, request, false /* for web socket */); } RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { this.client = client; this.originalRequest = originalRequest; this.forWebSocket = forWebSocket; this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket); } public RetryAndFollowUpInterceptor(OkHttpClient client, boolean forWebSocket) { this.client = client; this.forWebSocket = forWebSocket; }
- 主要是返回了new RealCall()对象,看来精髓都在这里面了
2.3: 现在来看下
.execute()
做了什么(RealCall.execute())final class RealCall implements Call { // ↓↓↓ synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } @Override public Response execute() throws IOException { // ↓↓↓ synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); try { client.dispatcher().executed(this); // ←←← Response result = getResponseWithInterceptorChain(); if (result == null) throw new IOException("Canceled"); return result; } finally { client.dispatcher().finished(this); // ←←← } } @Override public void enqueue(Callback responseCallback) { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); client.dispatcher().enqueue(new AsyncCall(responseCallback)); // ←←← } } public final class Dispatcher { private int maxRequests = 64; private int maxRequestsPerHost = 5; private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>(); private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>(); private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>(); synchronized void executed(RealCall call) { runningSyncCalls.add(call); // ←←← } synchronized void enqueue(AsyncCall call) { if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { runningAsyncCalls.add(call); // ←←← executorService().execute(call); // ←←← } else { readyAsyncCalls.add(call); } }