okhttp源码学习分析一

  • 同步请求
    • RealCall 的execute方法
  • 异步请求
    • enqueue源码

同步请求

public class GetExample {  OkHttpClient client = new OkHttpClient();  String run(String url) throws IOException {    //包含请求头,url,请求参数    Request request = new Request.Builder()        .url(url)        .build();    //newcall方法创建了realcall    try (Response response = client.newCall(request).execute()) {      return response.body().string();    }  }  public static void main(String[] args) throws IOException {    GetExample example = new GetExample();    String response = example.run("https://raw.github.com/square/okhttp/master/README.md");    System.out.println(response);  }}

RealCall 的execute方法

   @Override    public Response execute() throws IOException {        synchronized (this) {        //同一个RealCall 只能同时执行一个请求            if (executed) throw new IllegalStateException("Already Executed");            executed = true;        }        captureCallStackTrace();        timeout.enter();        eventListener.callStart(this);        try {        //将请求添加到dispatcher分发器里            client.dispatcher().executed(this);            //通过拦截链获取最后的结果,拦截链设计的很巧妙            Response result = getResponseWithInterceptorChain();            if (result == null) throw new IOException("Canceled");            return result;        } catch (IOException e) {            e = timeoutExit(e);            eventListener.callFailed(this, e);            throw e;        } finally {        //在分发器里将本次请求去掉            client.dispatcher().finished(this);        }    }

异步请求

client.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(Call call, IOException e) {            }            @Override            public void onResponse(Call call, Response response) throws IOException {            }        });

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

查看dispatcher的enqueue

/** Ready async calls in the order they'll be run. */  //准备执行异步的请求  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();  /** Running asynchronous calls. Includes canceled calls that haven't finished yet. */  //正在执行的异步请求  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();  /** Running synchronous calls. Includes canceled calls that haven't finished yet. */  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();    void enqueue(AsyncCall call) {    synchronized (this) {     //将该请求放到准备执行的异步请求栈里      readyAsyncCalls.add(call);      // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to      // the same host.      if (!call.get().forWebSocket) {        AsyncCall existingCall = findExistingCallWithHost(call.host());        if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);      }    }    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;  }

dispatcher类将多个网络请求进行分发管理。

更多相关文章

  1. Android倒计时实现
  2. android dialog 背景透明的样式
  3. Android之动态改变控件大小
  4. radiolog不全的问题
  5. Android中调试规范Log
  6. android音乐播放器(4)
  7. android service 生命周期
  8. Android(安卓)获取网络时间
  9. android 获取web 内容简单实现

随机推荐

  1. 如何解决php连接erp数据库失败
  2. 如何解决在php用gd库输出图片到微信浏览
  3. 详解PHP中php switch的方法实例
  4. 代码分析php中的回调函数
  5. PHP使用 is_numeric的实例解析
  6. PHP 使用 Trait 解决 PHP 单继承问题的实
  7. 详解PHP中password_hash的功能
  8. PHP中serialize的详细介绍
  9. php实现简单的登陆功能(附源码)
  10. PHP中unserialize的使用方法