对于OKHttp的一些理解(一)


OKHttp作为现在Android常用的网络三方框架,为AndroidCoders提供了极大的便利,在使用它的同时,我们也要去深入理解它的工作原理及机制。

概述

官网链接

一些常用的状态码

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

基本用法

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

我们根据源码构造器可以看到,它是一个Builder对象,如下:

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()方法,获取从服务器上请求下来的结果。

同步网络请求

源码:

@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()方法的具体实现。

/**
   * 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方法具体实现。

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()方法的具体实现。

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

猜你喜欢

转载自blog.csdn.net/u014643369/article/details/106077805