对于OKHttp的一些理解(一)


OKHttp做为如今Android经常使用的网络三方框架,为AndroidCoders提供了极大的便利,在使用它的同时,咱们也要去深刻理解它的工做原理及机制。

概述

官网连接java

一些经常使用的状态码

  • 100~199:指示信息,表示请求已接收,继续处理
  • 200~299:请求成功,表示请求已被成功接收、理解
  • 300~399:重定向,要完成请求必须进行更进一步的操做
  • 400~499:客户端错误,请求有语法错误或请求没法实现
  • 500~599:服务器端错误,服务器未能实现合法的请求

基本用法

  1. 建立OkHttpClient对象
//建立一个OkHttpClient对象
OkHttpClient client = new OkHttpClient();

咱们根据源码构造器能够看到,它是一个Builder对象,以下:git

public OkHttpClient() {
    this(new Builder());
}
public Builder() {
      dispatcher = new Dispatcher();
      protocols = DEFAULT_PROTOCOLS;
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      eventListenerFactory = EventListener.factory(EventListener.NONE);
      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;
    }
  1. 发起Http请求
//建立Request对象
Request request = new Request.Builder()
        .url(url)
        .build();
Response response = client.newCall(request).execute();

这里调用response.body().string()方法,获取从服务器上请求下来的结果。github

同步网络请求

源码:web

@Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } catch (IOException e) {
      eventListener.callFailed(this, e);
      throw e;
    } finally {
      client.dispatcher().finished(this);
    }
  }

具体用法:服务器

try {
   OkHttpClient client = new OkHttpClient();
   Request request = new Request.Builder()
                    .url("http://www.baidu.com/")
                    .build();
   Response response = client.newCall(request).execute();
   String result = response.body().string();
} catch (IOException e) {
   e.printStackTrace();
}

这里的execute方法,是Call接口里面的方法,源码就是RealCall实现类里面的execute()方法的具体实现。cookie

/** * Invokes the request immediately, and blocks until the response can be processed or is in * error. * * <p>To avoid leaking resources callers should close the {@link Response} which in turn will * close the underlying {@link ResponseBody}. * * <pre>@{code * * // ensure the response (and underlying response body) is closed * try (Response response = client.newCall(request).execute()) { * ... * } * * }</pre> * * <p>The caller may read the response body with the response's {@link Response#body} method. To * avoid leaking resources callers must {@linkplain ResponseBody close the response body} or the * Response. * * <p>Note that transport-layer success (receiving a HTTP response code, headers and body) does * not necessarily indicate application-layer success: {@code response} may still indicate an * unhappy HTTP response code like 404 or 500. * * @throws IOException if the request could not be executed due to cancellation, a connectivity * problem or timeout. Because networks can fail during an exchange, it is possible that the * remote server accepted the request before the failure. * @throws IllegalStateException when the call has already been executed. */
  Response execute() throws IOException;

异步网络请求

源码:网络

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

而后咱们去看dispatcher分发器里面的enqueue方法具体实现。app

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

具体用法:框架

OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("http://www.baidu.com/")
                .build();
        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()) {
                    throw new IOException("Unexpected code " + response);
                }
                String str = response.body().string();
                //TODO 这里获得的str就是返回的数据,并且这里仍是子线程,要更新UI请在主线程里面更新
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

这里的enqueue方法,是Call接口里面的方法,源码就是RealCall实现类里面的enqueue()方法的具体实现。less

/** * Schedules the request to be executed at some point in the future. * * <p>The {@link OkHttpClient#dispatcher dispatcher} defines when the request will run: usually * immediately unless there are several other requests currently being executed. * * <p>This client will later call back {@code responseCallback} with either an HTTP response or a * failure exception. * * @throws IllegalStateException when the call has already been executed. */
  void enqueue(Callback responseCallback);