總體流程:
okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new TokenInterceptor())
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.build();
通過builder模式建造okhttpclient,然後通過request把請求參數封裝起來,Requset構造函數如下:
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tags = Util.immutableMap(builder.tags);
}
然後okhttpClient通過newCall()把request對象轉換成Call對象
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
真正執行的是RealCall,然後通過同步方法execute()或異步方法enqueue()去執行網絡請求;
在execute()方法中:
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
timeout.enter();
eventListener.callStart(this);
try {
//標記該call正在執行
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
e = timeoutExit(e);
eventListener.callFailed(this, e);
throw e;
} 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(retryAndFollowUpInterceptor);
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));
//index=0
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
攔截器是用了責任鏈模式,下面看RealInterceptorChain類中的chain.proceed(originalRequest);
Interceptor.Chain是接口,RealInterceptorChain是實現類
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that the incoming request will use it.
if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
//這裏是從攔截器list中獲取一個攔截器
Interceptor interceptor = interceptors.get(index);
//然後調用攔截器的intercept(next)方法,並把從下一個攔截器開始的鏈當參數傳進去
Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed().
if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
}
// Confirm that the intercepted response isn't null.
if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
}
if (response.body() == null) {
throw new IllegalStateException(
"interceptor " + interceptor + " returned a response with no body");
}
return response;
}
第一個攔截器是我們自定義的攔截器,下面看我們自定義的攔截器:
private class TokenInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
....省略一些代碼
Request request = chain.request().newBuilder()
.header("auth-token", PreferencesUtil.getString( "accessToken") )
.build();
//繼續調用chain.proceed(request)
Response response = chain.proceed(request);
//Headers requestHeaders= response.networkResponse().request().headers();
//Log.d("simu4", "intercept: requestHeaders="+requestHeaders.toString());
MediaType mediaType = response.body().contentType();
Logger.i("response = "+response.toString());
if (isTokenExpired(response)) {
//同步請求方式,獲取最新的Token
Log.e("NetworkRequest.simu", "靜默自動刷新Token後 重新請求數據");
//同步請求方式,獲取最新的Token
String newSession = getNewToken();
//使用新的Token,創建新的請求
if (null != newSession && newSession.length() > 0) {
Request newRequest = chain.request()
.newBuilder()
.header("auth-token", newSession)
.build();
//重新請求上次的接口
return chain.proceed(newRequest.newBuilder().build());
}
}
//如果token正常返回結果
return response.newBuilder().body(ResponseBody.create(mediaType, resultStr)).build();
}else {
Request request = chain.request().newBuilder()
.header("Authorization", "Bearer "+(PreferencesUtil.getString( "accessToken") == null ? WindConstants.FROM_ANDROID : PreferencesUtil.getString( "accessToken")))
.build();
Logger.i("request toString="+request.toString());
Response response = chain.proceed(request);
//Headers requestHeaders= response.networkResponse().request().headers();
//Log.d("simu4", "intercept: requestHeaders="+requestHeaders.toString());
MediaType mediaType = response.body().contentType();
Logger.i("response = "+response.toString());
if (isTokenExpired(response)) {
//同步請求方式,獲取最新的Token
Log.e("NetworkRequest.simu", "靜默自動刷新Token後 重新請求數據");
//同步請求方式,獲取最新的Token
String newSession = getNewToken();
//使用新的Token,創建新的請求
if (null != newSession && newSession.length() > 0) {
Request newRequest = chain.request()
.newBuilder()
.header("Authorization", "Bearer "+newSession)
.build();
//重新請求上次的接口
return chain.proceed(newRequest.newBuilder().build());
}
}
//如果token正常返回結果
return response.newBuilder().body(ResponseBody.create(mediaType, resultStr)).build();
}
}
從上面代碼可以看到繼續回調chain.proceed(request);此時的chain是從下一個攔截器開始的,因此繼續回調RealInterceptorChain類中的process(),直到有一層攔截器返回結果,然後向上傳遞結果
異步執行:
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
Dispatcher中的enqueue()
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls.add(call);
}
promoteAndExecute();
}
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
把call放入readyAsyncCalls中,
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 (runningCallsForHost(asyncCall) >= maxRequestsPerHost) continue; // Host max capacity.
i.remove();
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(),把asyncCall放在線程池中執行
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);
eventListener.callFailed(RealCall.this, ioException);
responseCallback.onFailure(RealCall.this, ioException);
} finally {
if (!success) {
client.dispatcher().finished(this); // This call is no longer running!
}
}
}
然後看AsyncCall ,它繼承與NamedRunnable,NamedRunnable是一個抽象類,它實現了Runnable接口,在NamedRunnable的run方法中調用了execute(),execute()是抽象方法,因此會回調AsyncCall 中的execute()
@Override protected void execute() {
boolean signalledCallback = false;
timeout.enter();
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
e = timeoutExit(e);
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
仍然是調用getResponseWithInterceptorChain(),後面與同步方法一樣,只不過是放在線程池中執行,線程池如下:
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}