Okhttp的责任链模式分析

 

OkHttpClient的简单使用如下

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).get().build();
        Call call = client.newCall(request);
        call.enqueue(new xxCallBack());

 

在client.newCall(request)中,真正创建的是RealCall

    public Call newCall(Request request) {
        return new RealCall(this, request);
    }

所以call.enqueue也要到RealCall.enqueue中看

RealCall.java

    void enqueue(Callback responseCallback, boolean forWebSocket) {
        synchronized(this) {
            if (this.executed) {
                throw new IllegalStateException("Already Executed");
            }

            this.executed = true;
        }

        this.client.dispatcher().enqueue(new RealCall.AsyncCall(responseCallback,                     
          forWebSocket));
    }

 

    Dispatcher.java


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

    }

可以看到放到线程池的其实是AsyncCall,因为放到放程池的只能是Runnable对象,所以我们猜测AsyncCall一定是继承了Runnable。


//注:NamedRunnable implements Runnable 
public abstract class NamedRunnable implements Runnable {
    protected final String name;

    public NamedRunnable(String format, Object... args) {
        this.name = String.format(format, args);
    }

    public final void run() {
        String oldName = Thread.currentThread().getName();
        Thread.currentThread().setName(this.name);

        try {
            this.execute();
        } finally {
            Thread.currentThread().setName(oldName);
        }

    }

    protected abstract void execute();
}

可以看到,当线程池执行该任务时,会调用到run()方法里面的execute()方法,所以我们看看AsyncCall的execute()

        protected void execute() {
            boolean signalledCallback = false;

            try {
                Response response = RealCall.this.getResponseWithInterceptorChain(this.forWebSocket);
                if (RealCall.this.canceled) {
                    signalledCallback = true;
                    this.responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
                } else {
                    signalledCallback = true;
                    this.responseCallback.onResponse(RealCall.this, response);
                }
            } catch (IOException var6) {
                if (signalledCallback) {
                    Internal.logger.log(Level.INFO, "Callback failure for " + RealCall.this.toLoggableString(), var6);
                } else {
                    this.responseCallback.onFailure(RealCall.this, var6);
                }
            } finally {
                RealCall.this.client.dispatcher().finished(this);
            }

        }

先看看 Response response = RealCall.this.getResponseWithInterceptorChain(this.forWebSocket);


//RealCall.java
    private Response getResponseWithInterceptorChain(boolean forWebSocket) throws IOException {
        Chain chain = new RealCall.ApplicationInterceptorChain(0, this.originalRequest, forWebSocket);
        return chain.proceed(this.originalRequest);
    }

其实就是构建一个ApplicationInterceptorChain(index = 0)对象,调用proceed方法

        public Response proceed(Request request) throws IOException {
            if (this.index < RealCall.this.client.interceptors().size()) {
                Chain chain = RealCall.this.new ApplicationInterceptorChain(this.index + 1, request, this.forWebSocket);
                Interceptor interceptor = (Interceptor)RealCall.this.client.interceptors().get(this.index);
                Response interceptedResponse = interceptor.intercept(chain);
                if (interceptedResponse == null) {
                    throw new NullPointerException("application interceptor " + interceptor + " returned null");
                } else {
                    return interceptedResponse;
                }
            } else {
                return RealCall.this.getResponse(request, this.forWebSocket);
            }
        }

首先判断一下index < interceptors().size(),如果是,先创建一个index+1的ApplicationInterceptorChain,然后获取第index个Interceptor,然后调用interceptor.intercept(chain),这其实有点递归的意思,从第0个Interceptor开始,调用下一个的ApplicationInterceptorChain.proceed(),在proceed里面再调用interceptor.intercept(chain),直到index==size(),返回Response

 

那么,我们自定义的Interceptor里面需要做什么呢?最起码,需要在intercept(Chain chain)方法里面,调用chain.proceed(),使得整个递归可以进行下去。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值