OKHttp原理分析

xiaoxiao2021-02-28  60

最近生活上出了一些问题,对自己的人生也思考了很多,做安卓开发的程序员确实需要许多努力,可能你稍微有些懈怠就会被别人超过,甚至被行业淘汰,所以大家一定要多努力,但是同时也要注意自己的身体,身体出问题了其他的都成了空谈,好了废话就不多说了这里我们从调用流程上分析一下OKHttp的源码让大家对这个框架有所了解,希望能帮助到你们。

首先看我们的调用流程这里我们做一个简单的调用。

OkHttpClient okHttpClient = new OkHttpClient(); Request request=new Request.Builder() .url("http://www.baidu.com/") .build(); Call call= okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });

这是一个非常简单的异步请求,这里我们Request 的创建就不多讲了主要是Request 采用builder模式对一些常用的Request 属性进行设置。 这里我们先分析 Call call= okHttpClient.newCall(request);这个方法。

/** * Prepares the {@code request} to be executed at some point in the future. */ @Override public Call newCall(Request request) { return RealCall.newRealCall(this, request, false /* for web socket */); }

通过这里我们可以看到调用newCall的时候我们创建了一个RealCall对象并将它返回这个逻辑也挺清晰的不用做过多讲解。 在接下来的过程中我们又调用了call.enqueue(这个方法是调用异步请求的方法)方法,那接下来我们就要去分析RealCall的enqueue方法了,代码如下。

@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)); }

这里上面都是判断的方法我们着重分析最后一句 1.首先我们要明白client.dispatcher()是什么意思 2.其次我们要着重分析AsyncCall这个类 我们来看client.dispatcher我们首先找到了Dispatcher这个类的enqueue方法

synchronized void enqueue(AsyncCall call) { if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { runningAsyncCalls.add(call); executorService().execute(call); } else { readyAsyncCalls.add(call); } }

我们来看这里

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; }

意思是我们的dispatcher类做的工作是开启线程池执行网络请求通过executorService()得到线程池在通过execute来执行我们的请求那我们的AsyncCall那就肯定是一个Runnable接下来我们先看之前的执行过程

昨天有些太晚了没把博客整理完接下来我们继续分析下面是我重新整理的调度逻辑 从上图中我们可以看出我们的OKHttp中处理最核心的部分是我们的右侧在原始情亲经过一系列的拦截器的拦截处理后最终形成我们的CallBack以回调的形式将OKHttp处理的结果反馈给我们的调用层。 接下来我们首先分析RealIntercepterChail的process方法

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); Interceptor interceptor = interceptors.get(index); 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; }

其他的都是一些校验我们暂且不必考虑接下来我们要重点分析的是这一段代码

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);

在这里我们可以看到我们的拦截器链的处理是不断递归调用自己获取next 即下一个拦截器然后调用下一个拦截器的intercept方法,什么意思呢也就是说我们当前的拦截器调用 proceed方法后就会执行下一个拦截器的intercept方法不断递归知道执行到最后一层拦截器,下面我们通过具体拦截器的分析来说明这一点。 在这里OKHTTP使用了责任链模式,通过一层一层的拦截器最终将请求处理完全返回响应回调,在这里由于拦截器的处理比较复杂避免篇幅过大我们在下一篇文章中对拦截器进行逐个击破。

转载请注明原文地址: https://www.6miu.com/read-2619068.html

最新回复(0)