okhttp原理(面试一)

 //  构建okHttpClient,相当于请求的客户端,Builder设计模式
 		OkHttpClient okHttpClient = new OkHttpClient.Builder()
 		.readTimeout(5, TimeUnit.SECONDS)
	 	.build();
        // 构建一个请求体,同样也是Builder设计模式
        Request request = new Request.Builder()
        .url("http://www.baidu.com")
        .build();
        //  生成一个Call对象,该对象是接口类型,后面会说
        Call call = okHttpClient.newCall(request);
        try {
            //  拿到Response
            Response response = call.execute();
            Log.i("TAG",response.body().string());
        } catch (IOException e) {
        }

  1. 通过Builder模式创建OkHttpClient对象和Request对象
  2. 调用OkHttpClient的newCall方法,获取一个Call对象,参数是Request
  3. 调用execute方法获取一个Respone

首先Builder是OkHttpClient一个静态内部类,在Builder的构造函数中进行了一系列的初始化操作。包括了对Dispatcher与ConnectionPool初始化。
Dispatcher分发器,负责将每一次Requst进行分发,压栈到自己的线程池,并通过调用者自己不同的方式进行异步和同步处理。
ConnectionPool是一个连接池对象,它可以用来管理连接对象,从它的构造方法中可以看到连接池的默认空闲连接数为5个,keepAlive时间为5分钟。

 Call call = okHttpClient.newCall(request);

实际上创建的对象是Call的实现类RealCall 对象。

  Response response = call.execute();

这里其实是调用的是RealCall类的execute()方法。

@Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    timeout.enter();
    eventListener.callStart(this);
    try {
      client.dispatcher().executed(this);//通过此方法将call对象放入到同步请求队列中。
      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);
    }
}

在同步请求中Dispatcher主要负责了两件事,同步请求的保存和移除。
在这里插入图片描述
异步请求时client.newCall(request).enqueue();

RealCall.java

 @Override public void enqueue(Callback responseCallback) {
   
    //TODO 不能重复执行
    synchronized (this) {
   
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    //TODO 交给 dispatcher调度器 进行调度
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

利用dispatcher调度器,来进行实际的执行
client.dispatcher().enqueue(new AsyncCall(responseCallback));
在上面的OkHttpClient.Builder可以看出 已经初始化了Dispatcher。

 //TODO 执行异步请求
    synchronized void enqueue(AsyncCall call) {
   
        //TODO 同时请求不能超过并发数(64,可配置调度器调整)
        //TODO okhttp会使用共享主机即 地址相同的会共享socket
        //TODO 同一个host最多允许5条线程通知执行请求
        if (runningAsyncCalls.size() < maxRequests &&
                runningCallsForHost(call) < maxRequestsPerHost) {
   
            //TODO 加入运行队列 并交给线程池执行
            runningAsyncCalls
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值