Android_OkHttp源码分析

本文深入探讨了Android OkHttp的源码,包括Request构建、RealCall的执行过程以及拦截器的工作原理。重点分析了RealCall.execute()和enqueue()的区别,如何管理同步和异步请求,并详细解释了拦截器链在请求过程中的作用,如重试、缓存和网络连接。同时,文章还提供了构建对象的实例、测试代码和拦截器实现的责任链设计模式示例。
摘要由CSDN通过智能技术生成

Android_OkHttp源码分析


本文由 Luzhuo 编写,转发请保留该信息.
原文: http://blog.csdn.net/Rozol/article/details/72895794


基本使用

// 网络请求客户端,仅需一个即可
OkHttpClient client = new OkHttpClient()

// 构建请求
Request request = new Request.Builder().url(url).build();

// 同步请求
Response response = client.newCall(request).execute();

// 异步请求
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        e.printStackTrace();
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (!response.isSuccessful()) {
            if(callback != null) callback.onResonse(null);
            return;
        }
        callback.onResonse(response);
    }
});

源码分析

  • 1: 首先看下Request的构建, Request request = new Request.Builder().url(url).build()
public final class Request {
   
    public Builder() {
      this.method = "GET";
      this.headers = new Headers.Builder();
    }

    public Builder url(String url) {
      if (url == null) throw new NullPointerException("url == null");

      // Silently replace web socket URLs with HTTP URLs.
      if (url.regionMatches(true, 0, "ws:", 0, 3)) {
        url = "http:" + url.substring(3);
      } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
        url = "https:" + url.substring(4);
      }

      HttpUrl parsed = HttpUrl.parse(url);
      if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
      return url(parsed);
    }

    Request(Builder builder) {
        this.url = builder.url;
        this.method = builder.method;
        this.headers = builder.headers.build();
        this.body = builder.body;
        this.tag = builder.tag != null ? builder.tag : this;
    }

    public Request build() {
        if (url == null) throw new IllegalStateException("url == null");
        return new Request(this);
    }
}
- **主要是一些请求信息,如请求头,请求类型,请求数据,解析url等操作,主要看点是通过Build方式构建了Request**
  • 2.1: 先看下OkHttpClient client = new OkHttpClient(),OkHttpClient对象全局仅需要一个就可以了,现在看看里面做了什么?
public OkHttpClient() {
        this(new Builder());
}

public Builder() {
      dispatcher = new Dispatcher();
      protocols = DEFAULT_PROTOCOLS;
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      proxySelector = ProxySelector.getDefault();
      cookieJar = CookieJar.NO_COOKIES;
      socketFactory = SocketFactory.getDefault();
      hostnameVerifier = OkHostnameVerifier.INSTANCE;
      certificatePinner = CertificatePinner.DEFAULT;
      proxyAuthenticator = Authenticator.NONE;
      authenticator = Authenticator.NONE;
      connectionPool = new ConnectionPool();
      dns = Dns.SYSTEM;
      followSslRedirects = true;
      followRedirects = true;
      retryOnConnectionFailure = true;
      connectTimeout = 10_000;
      readTimeout = 10_000;
      writeTimeout = 10_000;
      pingInterval = 0;
}
 - 可见Builder()里主要做的还是初始化一些信息
  • 2.2: 然后OkHttpClient调用.newCall(request)

    @Override public Call newCall(Request request) {
        return new RealCall(this, request, false /* for web socket */);
    }
    
    RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
        this.client = client;
        this.originalRequest = originalRequest;
        this.forWebSocket = forWebSocket;
        this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
    }
    
    public RetryAndFollowUpInterceptor(OkHttpClient client, boolean forWebSocket) {
        this.client = client;
        this.forWebSocket = forWebSocket;
    }
    • 主要是返回了new RealCall()对象,看来精髓都在这里面了
  • 2.3: 现在来看下.execute()做了什么(RealCall.execute())

    final class RealCall implements Call {
        // ↓↓↓
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already Executed");
          executed = true;
        }
    
        @Override public Response execute() throws IOException {
            // ↓↓↓
            synchronized (this) {
              if (executed) throw new IllegalStateException("Already Executed");
              executed = true;
            }
            captureCallStackTrace();
            try {
              client.dispatcher().executed(this); // ←←←
              Response result = getResponseWithInterceptorChain();
              if (result == null) throw new IOException("Canceled");
              return result;
            } finally {
              client.dispatcher().finished(this); // ←←←
            }
        }
        @Override public void enqueue(Callback responseCallback) {
            synchronized (this) {
              if (executed) throw new IllegalStateException("Already Executed");
              executed = true;
            }
            captureCallStackTrace();
            client.dispatcher().enqueue(new AsyncCall(responseCallback)); // ←←←
        }
    }
    
    public final class Dispatcher {
         
        private int maxRequests = 64;
        private int maxRequestsPerHost = 5;
        private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
        private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
        private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
    
        synchronized void executed(RealCall call) {
            runningSyncCalls.add(call); // ←←←
        }
        synchronized void enqueue(AsyncCall call) {
            if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
              runningAsyncCalls.add(call); // ←←←
              executorService().execute(call); // ←←←
            } else {
              readyAsyncCalls.add(call);
            }
        }
    
        
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值