`
daojin
  • 浏览: 689972 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

OkHttp3.14解析

 
阅读更多
基本使用方式
创建Request

Request request = new Request.Builder().url().get().build(); 


创建OkHttpClient
OkHttpClient client = new OkHttpClient(); 
 
public final OkHttpClient client = new OkHttpClient.Builder() 
        .addInterceptor(new HttpLoggingInterceptor()) 
        .cache(new Cache(cacheDir, cacheSize)) 
        .build(); 
 
 
   OkHttpClient client = client.newBuilder() 
        .readTimeout(500, TimeUnit.MILLISECONDS) 
       .build(); 


执行
 Response response = client.newCall(request).execute();

client.newCall(request).enqueue(callback);


清理

client.dispatcher().executorService().shutdown();
client.connectionPool().evictAll();
 client.cache().close();


代码流程分析
创建RealCall
  private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
  }

  static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.

如果是同步的call
直接调用RealCall.execute

 private int maxRequests = 64;			
		  private int maxRequestsPerHost = 5;			
					
  @Override public Response execute() throws IOException {					
    synchronized (this) {					
      if (executed) throw new IllegalStateException("Already Executed");					
      executed = true;					
    }					
    transmitter.timeoutEnter();					
    transmitter.callStart();					
    try {					
      client.dispatcher().executed(this);					
      return getResponseWithInterceptorChain();					
    } finally {					
      client.dispatcher().finished(this);					
    }					
  }

如若调用enqueue方法,就会走到AsyncCall
  @Override public void enqueue(Callback responseCallback) {					
    synchronized (this) {					
      if (executed) throw new IllegalStateException("Already Executed");					
      executed = true;					
    }					
    transmitter.callStart();					
    client.dispatcher().enqueue(new AsyncCall(responseCallback));					
  }					
	

AsyncCall是Runnalbe 包装了callback

client.dispatcher().enqueue调用了promoteAndExecute  

  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 (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.					
					
        i.remove();					
        asyncCall.callsPerHost().incrementAndGet();					
        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(executorService());					
					

					
    /**					
     * Attempt to enqueue this async call on {@code executorService}. This will attempt to clean up					
     * if the executor has been shut down by reporting the call as failed.					
     */					
    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);					
        transmitter.noMoreExchanges(ioException);					
        responseCallback.onFailure(RealCall.this, ioException);					
      } finally {					
        if (!success) {					
          client.dispatcher().finished(this); // This call is no longer running!					
        }					
      }					
    }	

下面执行到了execute,调用 Response response = getResponseWithInterceptorChain();

 
   @Override protected void execute() {					
      boolean signalledCallback = false;					
      transmitter.timeoutEnter();					
      try {					
        Response response = getResponseWithInterceptorChain();					
        signalledCallback = true;					
        responseCallback.onResponse(RealCall.this, response);					
      } catch (IOException e) {					
        if (signalledCallback) {					
          // Do not signal the callback twice!					
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);					
        } else {					
          responseCallback.onFailure(RealCall.this, e);					
        }					
      } catch (Throwable t) {					
        cancel();					
        if (!signalledCallback) {					
          IOException canceledException = new IOException("canceled due to " + t);					
          canceledException.addSuppressed(t);					
          responseCallback.onFailure(RealCall.this, canceledException);					
        }					
        throw t;					
      } 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(new RetryAndFollowUpInterceptor(client));					
    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, transmitter, null, 0,					
        originalRequest, this, client.connectTimeoutMillis(),					
        client.readTimeoutMillis(), client.writeTimeoutMillis());					
					
    boolean calledNoMoreExchanges = false;					
    try {					
      Response response = chain.proceed(originalRequest);					
      if (transmitter.isCanceled()) {					
        closeQuietly(response);					
        throw new IOException("Canceled");					
      }					
      return response;					
    } catch (IOException e) {					
      calledNoMoreExchanges = true;					
      throw transmitter.noMoreExchanges(e);					
    } finally {					
      if (!calledNoMoreExchanges) {					
        transmitter.noMoreExchanges(null);					
      }					
    }					
  }					
RealInterceptorChain.proceed					
					
					
  public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)					
      throws IOException {					
					
					
 Response response = interceptor.intercept(next);					
					
}	


接下来走到Interceptor.intercept
RealCall.getResponseWithInterceptorChain 可以看到有四个					
    interceptors.add(new RetryAndFollowUpInterceptor(client));					
    interceptors.add(new BridgeInterceptor(client.cookieJar()));					
    interceptors.add(new CacheInterceptor(client.internalCache()));					
    interceptors.add(new ConnectInterceptor(client));					
CallServerInterceptor	



RetryAndFollowUpInterceptor 处理3XX重定向的,4XX授权,5xx服务器错误retry等

Location
  @Override public Response intercept(Chain chain)
Request followUp = followUpRequest(response, route);
 case HTTP_MULT_CHOICE:
      case HTTP_MOVED_PERM:
      case HTTP_MOVED_TEMP:
      case HTTP_SEE_OTHER:
        // Does the client allow redirects?
        if (!client.followRedirects()) return null;

        String location = userResponse.header("Location");


BridgeInterceptor
添加了很多header,并且加入了gzip

CacheInterceptor 处理cache
ConnectInterceptor 创建Exechange,建立连接
CallServerInterceptor 调用

exchange.writeRequestHeaders(request);					
					
  if (responseBuilder == null) {					
      responseBuilder = exchange.readResponseHeaders(false);					
    }					
					
    Response response = responseBuilder					
        .request(request)					
        .handshake(exchange.connection().handshake())					
        .sentRequestAtMillis(sentRequestMillis)					
        .receivedResponseAtMillis(System.currentTimeMillis())					
        .build();					
			



题外话:
ConnectionPool
最大5个链接,最长 5分钟
实现是RealConnectionPool

Http1.0 很明显无法复用socket链接。

Http2.0 可以复用socket链接







1
0
分享到:
评论

相关推荐

    okhttp-3.14.9-API文档-中英对照版.zip

    赠送jar包:okhttp-3.14.9.jar; 赠送原API文档:okhttp-3.14.9-javadoc.jar; 赠送源代码:okhttp-3.14.9-sources.jar; 赠送Maven依赖信息文件:okhttp-3.14.9.pom; 包含翻译后的API文档:okhttp-3.14.9-javadoc-...

    okhttp-3.14.9-API文档-中文版.zip

    赠送jar包:okhttp-3.14.9.jar; 赠送原API文档:okhttp-3.14.9-javadoc.jar; 赠送源代码:okhttp-3.14.9-sources.jar; 赠送Maven依赖信息文件:okhttp-3.14.9.pom; 包含翻译后的API文档:okhttp-3.14.9-javadoc-...

    okhttp-3.14.9+okio-1.17.2+kotlin-stdlib-1.3.72

    标题 "okhttp-3.14.9+okio-1.17.2+kotlin-stdlib-1.3.72" 提供了关于这个压缩包内容的关键信息,它包含的是三个重要的库:OkHttp 3.14.9 版本、Okio 1.17.2 版本以及 Kotlin 标准库 1.3.72 版本。这些库在Java和...

    okhttp网络框架

    **OkHttp 网络框架详解** OkHttp 是一个高效的、免费开源的网络通信库,由 Square 公司开发并维护。它以其简洁的 API 设计、强大的性能和丰富的特性在 Android 开发者中广受欢迎。OkHttp 的目标是简化网络请求的...

    okhttp-3.14.0

    okhttp网络通信包,okhttp3jar包是一款可以支持android网络框架之OKhttp的jar包,一个处理网络请求的开源项目,是目前android安卓端最火热的轻量级框架。

    okhttp-3.14.1.jar

    分享okhttp-3.14.1.jar下载,官方下载地址:https://square.github.io/okhttp/#download,目前官方已经是最新版本,不提供该版本jar下载。

    okHttp访问返回JSON,XML解析实例

    本篇将详细讲解如何使用OkHttp进行网络访问,并解析返回的JSON与XML数据。 首先,我们需要了解OkHttp的基本用法。OkHttp是一个异步的HTTP客户端,它通过减少网络延迟和内存使用来提高性能。创建一个OkHttpClient...

    Android OkHttp框架解析

    **Android OkHttp框架解析** OkHttp是Square公司推出的一个高效的HTTP客户端库,广泛应用于Android开发中,因其优秀的性能和简洁的API设计而受到开发者们的喜爱。OkHttp通过使用连接池、HTTP/2协议以及对现代网络...

    okhttp最新版okhttp-3.9.0.jar下载

    OkHttp旨在通过减少网络延迟和减少内存使用来提高应用程序的性能。这个版本的发布可能包含了性能优化、新功能、bug修复或对先前版本的改进。 描述中提到的"okio-1.6.0.jar"是OkHttp依赖的一个重要库,Okio是一个...

    详解Android OkHttp完全解析

    【Android OkHttp完全解析】 OkHttp是Square公司开发的一个高效的HTTP客户端库,广泛应用于Android开发中,用于处理网络请求。由于其性能优异、易于使用,它逐渐替代了Android原生的HttpClient。本文将全面解析...

    okhttp-3.14.7.jar

    javaweb常用jar包,javaee框架常用jar包,亲测可用,若需其他版本可给我留言

    okhttp-3.14.9.jar中文-英文对照文档.zip

    注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...

    OkHttp3源码解析(添加了详细注释)

    **OkHttp3源码解析** OkHttp3是Android平台上的一个高效、易用的网络通信库,由Square公司开发。它的出现解决了Android原生HttpURLConnection的性能问题,提供了更强大的功能和更好的网络请求管理。本解析主要围绕...

    okhttp3完整版JAR

    官方完整版okhttp3 maven &lt;groupId&gt;com.squareup.okhttp3&lt;/groupId&gt; &lt;artifactId&gt;okhttp (insert latest version) &lt;/dependency&gt;

    okhttp依赖包下载(java专用)

    OkHttp-3.12.8.jar 是 OkHttp 库的一个特定版本,包含了所有必要的类和资源文件,用于集成到 Java 项目中。这个版本发布于较早的时间,可能不包含最新特性或安全更新,但依然被许多项目所使用。如果你的新项目需要...

    okhttp封装json解析

    本示例将探讨如何利用OkHttp进行网络请求,并结合JSON解析来创建一个简单的网络请求工具。下面我们将详细介绍这个过程。 首先,我们需要了解OkHttp的基本用法。OkHttp是一个异步HTTP客户端,它通过连接池和协议协商...

    Android-Okhttp的使用解析

    在服务器端,你需要根据接收到的数据类型进行相应的解析,例如,如果是JSON格式,可以使用JSON解析库(如Jackson或Gson)进行解析;如果是表单数据,可以使用`request.getParameter()`方法获取参数。 5. **OkHttp...

    鸿洋大神的OkHttp源码,可导入直接使用

    《鸿洋大神的OkHttp源码解析及应用》 OkHttp是Android平台上广泛使用的网络请求库,由Square公司开发,以其高效、易用著称。鸿洋大神的OkHttp源码解析提供了深入理解这一工具的机会,让我们能够更好地利用其功能并...

Global site tag (gtag.js) - Google Analytics