APP中引入Retrofit和Okhttp之后,调用网络接口,只需要实现。
1.定义接口,包括请求方法的路径以及返回数据定义的数据对象类。
public interface MovieService {
@GET("api/columns/zhihuadmin")
Call<ColumnDetail> getColumns();
String baseUrl = "https://zhuanlan.zhihu.com/";//请求的baseUrl
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())//说明可以使用Gson结束返回的数据对象
.build();
MovieService movieService = retrofit.create(MovieService.class);//调用第一步定义的接口类
Call<ColumnDetail> call = movieService.getColumns();//
call.enqueue(new Callback<ColumnDetail>() {
@Override
public void onResponse(Call<ColumnDetail> call, Response<ColumnDetail> response) {
ColumnDetail detail = response.body();//在这里就获取到了服务器返回的数据
show_content.setText(new Gson().toJson(detail));
}
@Override
public void onFailure(Call<ColumnDetail> call, Throwable t) {
show_content.setText(t.getMessage());
}
});
就是这么简单。项目中逻辑稍微复杂,是因为对Okhttp的设置以及Retrofit的初始化等进行了优化。那么,调用过程中,内部是如何一步步的最终调用网络请求的呢? 触发执行网络请求的是enqueue这个方法,断点调试call对象实际是RealCall
override fun enqueue(responseCallback: Callback) {
check(executed.compareAndSet(false, true)) { "Already Executed" }
callStart()
client.dispatcher.enqueue(AsyncCall(responseCallback))
}
Dispatcher.class
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
直接放到线程池executorService中执行。enqueue(new AsyncCall(responseCallback, forWebSocket))可知执行的时候调用的是AsyncCall中的execute方法。
override fun run() {
threadName("OkHttp ${redactedUrl()}") {
...
try {
val response = getResponseWithInterceptorChain()
signalledCallback = true
responseCallback.onResponse(this@RealCall, response)
}
...
}
}
internal fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors
interceptors += RetryAndFollowUpInterceptor(client)
interceptors += BridgeInterceptor(client.cookieJar)
interceptors += CacheInterceptor(client.cache)
interceptors += ConnectInterceptor
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
interceptors += CallServerInterceptor(forWebSocket)
...
var calledNoMoreExchanges = false
try {
val response = chain.proceed(originalRequest)
...
return response
}
...
}
object ConnectInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val realChain = chain as RealInterceptorChain
val exchange = realChain.call.initExchange(chain)
val connectedChain = realChain.copy(exchange = exchange)
return connectedChain.proceed(realChain.request)
}
}
RealCall中调用getResponseWithInterceptorChain返回response,里面new了一个 RealInterceptorChain,里面传了5个默认的Interceptor。当调用chain.proceed(originalRequest)的时候,实际上是调用了第一个也就是RetryAndFollowUpInterceptor的intercept。
最终调用的是CallServerInterceptor的intercept方法。
@Override public Response intercept(Chain chain) throws IOException {
...
httpCodec.writeRequestHeaders(request);
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
...
request.body().writeTo(bufferedRequestBody);
bufferedRequestBody.close();
realChain.eventListener()
.requestBodyEnd(realChain.call(), requestBodyOut.successfulCount);
} else if (!connection.isMultiplexed()) {
// If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection
// from being reused. Otherwise we're still obligated to transmit the request body to
// leave the connection in a consistent state.
streamAllocation.noNewStreams();
}
}
httpCodec.finishRequest();
Response response = responseBuilder
.request(request)
.handshake(streamAllocation.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
realChain.eventListener()
.responseHeadersEnd(realChain.call(), response);
...
return response;
}
StreamAllocation是什么时候创建的?
作用:主要协调Connections、Streams、Calls几个类的关系
ConnectInterceptor中执行了RealConnection connection = streamAllocation.connection();真正的返回一个RealConnection对象建立了连接
ConnectInterceptor.class
@Override public Response intercept(Chain chain) throws IOException {
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Request request = realChain.request();
StreamAllocation streamAllocation = realChain.streamAllocation();//从RealInterceptorChain读取的对象
...
}
这个是通过RealCall层级调用getResponseWithInterceptorChain()里面先new一个RealInterceptorChain(),但是这个时候new的是null。也就是说,在层级调用的时候创建了StreamAllocation。 肯定在RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor、CallServerInterceptor这几个类里面。
RetryAndFollowUpInterceptor 每个调试发现在这里
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Call call = realChain.call();
EventListener eventListener = realChain.eventListener();
streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(request.url()),
call, eventListener, callStackTrace);