this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
this.callTimeout = builder.callTimeout;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
}
//…省略代码…
public static final class Builder {
Dispatcher dispatcher;
final List interceptors = new ArrayList<>();
final List networkInterceptors = new ArrayList<>();
//…省略部分参数…
boolean retryOnConnectionFailure;
int callTimeout;
int connectTimeout;
int readTimeout;
int writeTimeout;
public Builder() {
dispatcher = new Dispatcher();
eventListenerFactory = EventListener.factory(EventListener.NONE);
//…省略部分参数…
retryOnConnectionFailure = true;
callTimeout = 0;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
}
//…省略代码…
public OkHttpClient build() {
return new OkHttpClient(this);
}
}
}
这就是一个标准的构建者模式,将http请求的一些配置封装到client对象中。
#### 2\. 构建Request请求对象
public final class Request {
final HttpUrl url;
final String method;
final Headers headers;
final @Nullable RequestBody body;
final Map<Class<?>, Object> tags;
public static class Builder {
@Nullable HttpUrl url;
String method;
Headers.Builder headers;
@Nullable RequestBody body;
public Builder() {
this.method = “GET”;
this.headers = new Headers.Builder();
}
Builder(Request request) {
this.url = request.url;
this.method = request.method;
this.body = request.body;
this.tags = request.tags.isEmpty()
? Collections.emptyMap()
: new LinkedHashMap<>(request.tags);
this.headers = request.headers.newBuilder();
}
}
}
这也是一个建造者模式把请求的`url`、`method`、`header`全部封装到`Request`对象中。
### 3\. 创建Call对象
先来看看Call,这是一个接口,定义了一些`request()`、`enqueue(Callback responseCallback)`、`execute()`等方法,其实现类是RealCall,先搁置一边。回过头来看`client.newCall(request)`跟进代码,查看`newCall(Request request)`方法。
`OkHttpClient`类:
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
RealCall类:
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
果然,这里就只是跟进传进来的Request和当前的client对象创建了一个RealCall对象,也就是说使用方法中的第三步(`Call call = client.newCall(request)`)执行完成后,得到了一个ReallCall对象,接下来到了第四步。
#### 4\. 发起请求
先看`execute = call.execute()`请求
###### a).同步请求execute()
@Override
public Response execute() throws IOException {
synchronized (this) {
//一个请求只能执行一次
if (executed) throw new IllegalStateException(“Already Executed”);
executed = true;
}
captureCallStackTrace();
timeout.enter();
//http请求调用的生命周期
eventListener.callStart(this);
try {
client.dispatcher().executed(this);//注释1
Response result = getResponseWithInterceptorChain();//注释2
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);
}
}
关键代码为标出来的注释1和注释2两处,先看注释1,看下`client.dispatcher()`返回的`Dispatcher`对象:
/**
* Policy on when async requests are executed.
*
*
Each dispatcher uses an {@link ExecutorService} to run calls internally. If you supply your
* own executor, it should be able to run {@linkplain #getMaxRequests the configured maximum} number
* of calls concurrently.
/public final class Dispatcher {
//最大请求数
private int maxRequests = 64;
//每一个主机的最大请求数
private int maxRequestsPerHost = 5;
private @Nullable Runnable idleCallback;
/* Executes calls. Created lazily. /
//线程池
private @Nullable ExecutorService executorService;
/* Ready async calls in the order they’ll be run. /
//准备执行的异步请求队列
private final Deque readyAsyncCalls = new ArrayDeque<>();
/* Running asynchronous calls. Includes canceled calls that haven’t finished yet. /
//正在执行的异步请求队列
private final Deque runningAsyncCalls = new ArrayDeque<>();
/* Running synchronous calls. Includes canceled calls that haven’t finished yet. /
//正在执行的同步请求队列
private final Deque runningSyncCalls = new ArrayDeque<>();
public Dispatcher(ExecutorService executorService) {
this.executorService = executorService;
}
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls.add(call);
// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
// the same host.
if (!call.get().forWebSocket) {
AsyncCall existingCall = findExistingCallWithHost(call.host());
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
}
}
promoteAndExecute();
}
/* Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
//…代码略…
}
这是一个调度器,内部维护着最大请求数,每个主机最大请求数等参数,最重要的是维护着三个队列,分别是“将要执行的异步请求队列”、“正在执行的异步请求队列”和“正在执行的同步执行队列”。之前的代码段中注释1处调用`dispatcher.executed(this)`方法,我们看到这个方法只是把当前的realCall实例加入到了请求队列中。接下来看注释2处的代码`Response result = getResponseWithInterceptorChain()`,看下这个方法:
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List 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));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
在这个方法中,将用户自定义的一些拦截器和默认的拦截器封装到一个list中,然后创建`RealInterceptorChain`对象并执行`proceed(originalRequest)`方法,接下来将是重点。看一下这个方法
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
//…省去异常处理…
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request, call,eventListener, connectTimeout, readTimeout,writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
//…省去异常处理…
return response;
}
关键代码只有三行,这里会遍历调用拦截器列表中的拦截器,并调用每一个拦截器的`intercept(RealInterceptorChain chain)`方法,先看这里的第一个拦截器`RetryAndFollowUpInterceptor`的`intercept(Chain chain)`方法
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RealInterceptorChain realChain = (RealInterceptorChain) chain;
//…省略部分代码…
int followUpCount = 0;
Response priorResponse = null;
while (true) {
//…省略异常处理代码…
Response response;
boolean releaseConnection = true;
try {
//注释3
response = realChain.proceed(request, streamAllocation, null, null);
releaseConnection = false;
} catch (RouteException e) {
// The attempt to connect via a route failed. The request will not have been sent.
if (!recover(e.getLastConnectException(), streamAllocation, false, request)) {
throw e.getFirstConnectException();
}
releaseConnection = false;
continue;
} catch (IOException e) {
// An attempt to communicate with a server failed. The request may have been sent.
boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
if (!recover(e, streamAllocation, requestSendStarted, request)) throw e;
releaseConnection = false;
continue;
} finally {
// We’re throwing an unchecked exception. Release any resources.
if (releaseConnection) {
streamAllocation.streamFailed(null);
streamAllocation.release(true);
}
}
// Attach the prior response if it exists. Such responses never have a body.
if (priorResponse != null) {
response = response.newBuilder()
.priorResponse(priorResponse.newBuilder()
.body(null)
.build())
.build();
}
Request followUp;
try {
followUp = followUpRequest(response, streamAllocation.route());
} catch (IOException e) {
streamAllocation.release(true);
throw e;
}
if (followUp == null) {
streamAllocation.release(true);
return response;
}
closeQuietly(response.body());
if (++followUpCount > MAX_FOLLOW_UPS) {
streamAllocation.release(true);
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
if (followUp.body() instanceof UnrepeatableRequestBody) {
streamAllocation.release(true);
throw new HttpRetryException(“Cannot retry streamed HTTP body”, response.code());
}
if (!sameConnection(response, followUp.url())) {
streamAllocation.release(false);
streamAllocation = new StreamAllocation(client.connectionPool(),
createAddress(followUp.url()), call, eventListener, callStackTrace);
this.streamAllocation = streamAllocation;
} else if (streamAllocation.codec() != null) {
throw new IllegalStateException(“Closing the body of " + response
+ " didn’t close its backing stream. Bad interceptor?”);
}
request = followUp;
priorResponse = response;
}
}
在一个`while(true)`中执行,当重连次数`followUpCount`超过20次的时候,停止重连。当执行到注释3的时候,又会重新执行`RealInterceptorChain.proceed()`方法。但是这次会取出下一个拦截器`BridgeInterceptor`并执行它的`intercept(Chain chain`)方法。以这种方式就会遍历完拦截器list中的拦截器,并调用响应的`intercept`方法,接下来的几个拦截器的`intercept`方法比较简单,就不分析了。同样也会在此方法中调用`realChain.proceed()`方法进入下一个拦截器,直到最后一个拦截器`CallServerInterceptor`,看下它的`intercept`方法:
@Override public Response intercept(Chain chain) throws IOException { final RealInterceptorChain realChain = (RealInterceptorChain) chain; //…省略代码 realChain.eventListener().requestHeadersStart(call); //向服务端发起请求 httpCodec.writeRequestHeaders(request); realChain.eventListener().requestHeadersEnd(call, request); Response.Builder responseBuilder = null; //如果Request请求的body不为空,需要包装RequestBody并发送 if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) { //…省略代码… if (responseBuilder == null) { if (request.body() instanceof DuplexRequestBody) { //…省略代码… } else { // Write the request body if the “Expect: 100-continue” expectation was met. realChain.eventListener().requestBodyStart(call); //获取body内容的长度 long contentLength = request.body().contentLength(); CountingSink requestBodyOut = new CountingSink(httpCodec.createRequestBody(request, contentLength)); BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut); //发送RequestBody request.body().writeTo(bufferedRequestBody); bufferedRequestBody.close(); realChain.eventListener().requestBodyEnd(call, requestBodyOut.successfulCount); } } else if (!connection.isMultiplexed()) { // …省略代码… } } //完成请求 if (!(request.body() instanceof DuplexRequestBody)) { httpCodec.finishRequest(); } if (responseBuilder == null) { realChain.eventListener().responseHeadersStart(call); //读取返回的Response responseBuilder = httpCodec.readResponseHeaders(false); } //构建Response responseBuilder .request(request) .handshake(streamAllocation.connection().handshake()) .sentRequestAtMillis(sentRequestMillis) .receivedResponseAtMillis(System.currentTimeMillis()); Internal.instance.initCodec(responseBuilder, httpCodec); Response response = responseBuilder.build(); //…省略了Response的code==100的处理… if (forWebSocket && code == 101) { // Connection is upgrading, but we need to ensure interceptors see a non-null response body. // 构建一个非空的Response返回 } else { response = response.newBuilder() .body(httpCodec.openResponseBody(response)) .build(); } //…关闭资源… //…异常处理… return response; }
下面详细分析一下这个方法:分析这个方法之前我们先看`HttpCodec`这个接口的介绍`Encodes HTTP requests and decodes HTTP responses`。编码http请求并解码http返回结果,也就是说真正的处理请求和结果的是这个接口,它有两个实现类分别是`Http1Codec`和`Http2Codec`分别对应Http/1.x和Http/2.x。
好了,开始继续之前的分析,首先通过`httpCodec.writeRequestHeaders(request)`发起请求,以`Http1Codec`为例
/** * Prepares the HTTP headers and sends them to the server. * *
For streaming requests with a body, headers must be prepared before the * output stream has been written to. Otherwise the body would need to be buffered! * *
For non-streaming requests with a body, headers must be prepared after the * output stream has been written to and closed. This ensures that the {@code Content-Length} * header field receives the proper value. */ @Override public void writeRequestHeaders(Request request) throws IOException { String requestLine = RequestLine.get( request, streamAllocation.connection().route().proxy().type()); writeRequest(request.headers(), requestLine); }
文末
初级工程师拿到需求会直接开始做,然后做着做着发现有问题了,要么技术实现不了,要么逻辑有问题。
而高级工程师拿到需求会考虑很多,技术的可行性?对现有业务有没有帮助?对现有技术架构的影响?扩展性如何?等等…之后才会再进行设计编码阶段。
而现在随着跨平台开发,混合式开发,前端开发之类的热门,Android开发者需要学习和掌握的技术也在不断的增加。
通过和一些行业里的朋友交流讨论,以及参考现在大厂面试的要求。我们花了差不多一个月时间整理出了这份Android高级工程师需要掌握的所有知识体系。你可以看下掌握了多少。
混合式开发,微信小程序。都是得学会并且熟练的
这些是Android相关技术的内核,还有Java进阶
高级进阶必备的一些技术。像移动开发架构项目实战等
Android前沿技术;包括了组件化,热升级和热修复,以及各种架构跟框架的详细技术体系
以上即是我们整理的Android高级工程师需要掌握的技术体系了。可能很多朋友觉得很多技术自己都会了,只是一些新的技术不清楚而已。应该没什么太大的问题。
而这恰恰是问题所在!为什么别人高级工程师能年限突破30万,而你只有十几万呢?
就因为你只需补充你自己认为需要的,但并不知道企业需要的。这个就特别容易造成差距。因为你的技术体系并不系统,是零碎的,散乱的。那么你凭什么突破30万年薪呢?
我这些话比较直接,可能会戳到一些人的玻璃心,但是我知道肯定会对一些人起到点醒的效果的。而但凡只要有人因为我的这份高级系统大纲以及这些话找到了方向,并且付出行动去提升自我,为了成功变得更加努力。那么我做的这些就都有了意义。
喜欢的话请帮忙转发点赞一下能让更多有需要的人看到吧。谢谢!
上即是我们整理的Android高级工程师需要掌握的技术体系了。可能很多朋友觉得很多技术自己都会了,只是一些新的技术不清楚而已。应该没什么太大的问题。
而这恰恰是问题所在!为什么别人高级工程师能年限突破30万,而你只有十几万呢?
就因为你只需补充你自己认为需要的,但并不知道企业需要的。这个就特别容易造成差距。因为你的技术体系并不系统,是零碎的,散乱的。那么你凭什么突破30万年薪呢?
我这些话比较直接,可能会戳到一些人的玻璃心,但是我知道肯定会对一些人起到点醒的效果的。而但凡只要有人因为我的这份高级系统大纲以及这些话找到了方向,并且付出行动去提升自我,为了成功变得更加努力。那么我做的这些就都有了意义。