Retrofit中的OkHttp
来源:互联网 发布:淘宝违规记录多久清除 编辑:程序博客网 时间:2024/06/06 03:21
OkHttp中的Request
Request
在RealCall中的内部类ApplicationInterceptorChain中
private final Request request;
在构造方法中,初始化了该request
ApplicationInterceptorChain(int index, Request request, boolean forWebSocket) { this.index = index; this.request = request; this.forWebSocket = forWebSocket; }
并在RealCall中的getResponseWithInterceptorChain方法中创建了该对象
private Response getResponseWithInterceptorChain(boolean forWebSocket) throws IOException { Interceptor.Chain chain = new ApplicationInterceptorChain(0, originalRequest, forWebSocket); return chain.proceed(originalRequest); }
而RealCall中的originalRequest变量是在构造方法中被赋值的
protected RealCall(OkHttpClient client, Request originalRequest) { this.client = client; this.originalRequest = originalRequest; }
也就是说,创建RealCall对象,需要Request对象。
在OkHttpClient类中创建了RealCall
@Override public Call newCall(Request request) { return new RealCall(this, request); }
在OkHttpCall中,调用了该newCall方法。
private okhttp3.Call createRawCall() throws IOException { Request request = serviceMethod.toRequest(args); okhttp3.Call call = serviceMethod.callFactory.newCall(request); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; }
接着看OkHttpCall中的args和serviceMethod的来源。
OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) { this.serviceMethod = serviceMethod; this.args = args; }
可以追踪到在Retrofit中的create方法中
ServiceMethod serviceMethod = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall持有args和serviceMethod对象。通过createRawCall方法中的这一句,来创建了Request对象。
Request request = serviceMethod.toRequest(args);
在ServiceMethod的toRequest方法中,通过构建RequestBuilder,来创建Request对象。
Request toRequest(Object... args) throws IOException { RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types. ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers; int argumentCount = args != null ? args.length : 0; if (argumentCount != handlers.length) { throw new IllegalArgumentException("Argument count (" + argumentCount + ") doesn't match expected count (" + handlers.length + ")"); } for (int p = 0; p < argumentCount; p++) { handlers[p].apply(requestBuilder, args[p]); } return requestBuilder.build(); }
下面整体捋下思路。当在通过Retrofit执行下面这段代码时候,
MyApi api = retrofit.create(MyApi.class);
将会在Retrofit的create方法中创建ServiceMethod对象。并根据此对象和方法参数args来构建OkHttpCall对象。
当执行下面这段代码时候
call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { } @Override public void onFailure(Call<String> call, Throwable t) { } });
将会调用OkHttpCall中的enqueue方法。在此方法中首先会根据ServiceMethod对象和args来创建Request对象,再根据Request来创建RealCall对象。当执行OkHttpCall中的enqueue方法时,将会执行RealCall中的enqueue方法。
void enqueue(Callback responseCallback, boolean forWebSocket) { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } client.dispatcher().enqueue(new AsyncCall(responseCallback, forWebSocket)); }
此方法会调用Dispatcher类中的enqueue()方法
synchronized void enqueue(AsyncCall call) { if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { runningAsyncCalls.add(call); executorService().execute(call); } else { readyAsyncCalls.add(call); } }
Dispatcher类中持有线程池。直接通过线程池,来执行任务。
AsyncCall
首先来看AsyncCall的继承结构
AsyncCall extends NamedRunnable extends Runnable
在NamedRunnable中
protected abstract void execute();
所以Dispatcher中线程池执行的任务其实是AsyncCall中的execute()方法中的内容
在AsyncCall的execute()方法中
@Override protected void execute() { boolean signalledCallback = false; try { Response response = getResponseWithInterceptorChain(forWebSocket); } catch (IOException e) { } finally { client.dispatcher().finished(this); } }
上段代码中调用了RealCall中的getResponseWithInterceptorChain()方法。
在RealCall中有:
private Response getResponseWithInterceptorChain(boolean forWebSocket) throws IOException { Interceptor.Chain chain = new ApplicationInterceptorChain(0, originalRequest, forWebSocket); return chain.proceed(originalRequest); }
上段代码调用了RealCall的内部类ApplicationInterceptorChain中的proceed()方法。
在ApplicationInterceptorChain中有:
@Override public Response proceed(Request request) throws IOException { // If there's another interceptor in the chain, call that. if (index < client.interceptors().size()) { Interceptor.Chain chain = new ApplicationInterceptorChain(index + 1, request, forWebSocket); Interceptor interceptor = client.interceptors().get(index); Response interceptedResponse = interceptor.intercept(chain); if (interceptedResponse == null) { throw new NullPointerException("application interceptor " + interceptor + " returned null"); } return interceptedResponse; } // No more interceptors. Do HTTP. return getResponse(request, forWebSocket); }
最后执行RealCall中的getResponse()方法
在RealCall中有:
Response getResponse(Request request, boolean forWebSocket) throws IOException { RequestBody body = request.body(); if (body != null) { Request.Builder requestBuilder = request.newBuilder(); MediaType contentType = body.contentType(); if (contentType != null) { requestBuilder.header("Content-Type", contentType.toString()); } long contentLength = body.contentLength(); if (contentLength != -1) { requestBuilder.header("Content-Length", Long.toString(contentLength)); requestBuilder.removeHeader("Transfer-Encoding"); } else { requestBuilder.header("Transfer-Encoding", "chunked"); requestBuilder.removeHeader("Content-Length"); } //1 创建request对象 request = requestBuilder.build(); } //2 创建HttpEngine engine = new HttpEngine(client, request, false, false, forWebSocket, null, null, null); int followUpCount = 0; while (true) { if (canceled) { //3 如果取消了 释放engine engine.releaseStreamAllocation(); throw new IOException("Canceled"); } boolean releaseConnection = true; try { //4 发送请求 engine.sendRequest(); engine.readResponse(); releaseConnection = false; } catch (RequestException e) { // The attempt to interpret the request failed. Give up. throw e.getCause(); } catch (RouteException e) { // The attempt to connect via a route failed. The request will not have been sent. HttpEngine retryEngine = engine.recover(e.getLastConnectException(), true, null); if (retryEngine != null) { releaseConnection = false; engine = retryEngine; continue; } // Give up; recovery is not possible. throw e.getLastConnectException(); } catch (IOException e) { // An attempt to communicate with a server failed. The request may have been sent. HttpEngine retryEngine = engine.recover(e, false, null); if (retryEngine != null) { releaseConnection = false; engine = retryEngine; continue; } // Give up; recovery is not possible. throw e; } finally { // We're throwing an unchecked exception. Release any resources. if (releaseConnection) { StreamAllocation streamAllocation = engine.close(); streamAllocation.release(); } } Response response = engine.getResponse(); Request followUp = engine.followUpRequest(); if (followUp == null) { if (!forWebSocket) { engine.releaseStreamAllocation(); } return response; } StreamAllocation streamAllocation = engine.close(); if (++followUpCount > MAX_FOLLOW_UPS) { streamAllocation.release(); throw new ProtocolException("Too many follow-up requests: " + followUpCount); } if (!engine.sameConnection(followUp.url())) { streamAllocation.release(); streamAllocation = null; } else if (streamAllocation.stream() != null) { throw new IllegalStateException("Closing the body of " + response + " didn't close its backing stream. Bad interceptor?"); } request = followUp; engine = new HttpEngine(client, request, false, false, forWebSocket, streamAllocation, null, response); } }
- Retrofit中的OkHttp
- OKhttp+Retrofit
- RxJava+Retrofit+OkHttp组合在网络请求中的简单配置
- flux-retrofit-okhttp封装
- Retrofit+RxJava+OKhttp+RxBus
- retrofit+okhttp+rxjava
- 初涉Retrofit+OKHttp
- Rxjava 、Retrofit、Okhttp整合
- Rxjava+ReTrofit+okHttp深入浅出
- Retrofit 2.0 + OkHttp 3.0
- Retrofit+okhttp基本使用
- Retrofit+okhttp 缓存的
- Retrofit+OkHttp+RxAndroid
- android:retrofit+OKHttp使用
- retrofit+okhttp 实现缓存
- 网络框架-retrofit,okhttp
- RxJava+Retrofit+OkHttp实战
- Retrofit+Okhttp+RxJava
- CentOS6下源码安装php7
- Mysql Delete inner jion 删除数据
- Java注解Annotation 完成验证
- java笔记--关于线程同步(5种同步方式)
- Lua中的关系类元方法
- Retrofit中的OkHttp
- 生成v字且点击切换
- MySQL的主从备份
- Linux指令--nl
- geth1.7搭建多节点私有链
- (再次更新)打造RecyclerView万能适配器,上拉刷新,下拉加载
- 关于AFN及webview中的cookie
- 商场中精确定位用户所在店铺
- DNS