三方框架必学系列#OkHttp

76 阅读12分钟

三方框架必学系列#EventBus

三方框架必学系列#Rxjava

三方框架必学系列#Retrofit

三方框架必学系列#OkHttp

三方框架必学系列#Glide

三方框架必学系列#屏幕适配

一.基本使用

1.依赖引入

implementation 'com.squareup.okhttp3:okhttp:3.5.0'

2.请求使用

public class OkHttpUtils {
    private final static String url = "https://www.httpbin.org/";
    private static OkHttpUtils instance;

    private OkHttpClient okHttpClient = new OkHttpClient();

    private OkHttpUtils() {
    }

    public static OkHttpUtils getInstance() {
        if (null == instance) {
            synchronized (OkHttpUtils.class) {
                if (null == instance) {
                    instance = new OkHttpUtils();
                }
            }
        }
        return instance;
    }

    //同步get请求
    public void synGet() {


        Request request = new Request.Builder().url(url + "get?username=123&password=123").build();
        try {
            Response response = okHttpClient.newCall(request)
            .execute();
            System.out.println("threadName:" + Thread.currentThread().getName());
            System.out.println(Objects.requireNonNull(response.body().string()));
        } catch (IOException | NullPointerException e) {
            e.printStackTrace();
        }
    }

    //异步get请求
    public void aSynGet() {
        Request request = new Request.Builder().url(url + "get?username=123&password=123").get().build();
        startCall(request);
    }

    // form表单 post请求 contentType application/x-www-form-urlencoded,multipart/form-data:需要在表单中进行文件上传时,就需要使用该格式
    public void postForm() {
        FormBody formBody = new FormBody.Builder().add("use", "abc")
        .add("pwd", "123").build();
        Request request = new Request.Builder().url(url + "post").post(formBody).build();
        startCall(request);
    }

    //post请求上传二进制文件,只上传单个文件  contentType可查看菜鸟教程https://www.runoob.com/http/http-content-type.html
    public void postOctStream() {
        try {
            RequestBody streamBody = RequestBody.create(MediaType.parse("application/octet-stream"), "123".getBytes("utf-8"));
            UploadRequestBody uploadRequestBody = new UploadRequestBody(new UploadRequestBody.ProgressListener() {
                @Override
                public void progress(String progress, long contentLength, long currentWrite) {
                    System.out.println("progress:" + progress + "contentLength:" + contentLength + ",currentWrite:" + currentWrite);
                }
            }, streamBody);
            Request request = new Request.Builder().url(url + "post").post(uploadRequestBody).build();
            startCall(request);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    //post多类型上传
    public void postMultiPart() {
        try {
            MultipartBody multipartBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("username", "abc")
            .addFormDataPart("pwd", "123")
            .addFormDataPart("file", "fileName",
                             RequestBody.create(MediaType.parse("application/octet-stream"), "123".getBytes("utf-8"))).build();
            Request request = new Request.Builder().url(url + "post").post(multipartBody).build();
            startCall(request);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    //下载
    public void downloadImage(ImageView imageView) {

        Request request = new Request.Builder().get().url("https://img0.baidu.com/it/u=1501084209,93021381&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500")
                .build();
        startCall(request, imageView);


    }

    /**
     * 普通拦截器和网络拦截器
     */
    public void addDownLoadInterceptor() {
        okHttpClient=okHttpClient.newBuilder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        //前置处理 添加请求头等等
                        Request request = chain.request().newBuilder()
                                .addHeader("os", "android")
                                .addHeader("version", "1.o")
                                .build();

                        Response response = chain.proceed(request);
                        //后置处理
                        return response;
                    }
                }).addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {

                        //网路拦截器中配置下载拦截器
                        System.out.println("version>>>>>" + chain.request().header("version"));
                        Response response = chain.proceed(chain.request());
//                        return chain.proceed(chain.request());
                        return  response.newBuilder().body(new ProgressResponseBody(response.body(), new ProgressResponseBody.ProgressListener() {
                            @Override
                            public void progress(String progress, long contentLength, long currentWrite) {
                                System.out.println("addInterceptor----progress:"+progress+",contentLength:"+contentLength+",currentWrite:"+currentWrite);
                            }
                        })).build();
                    }
                }).build();
    }

    /**
     * 文件上传拦截器
     */
    public void addUpLoadInterceptor() {
        okHttpClient=okHttpClient.newBuilder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        //前置处理 添加请求头等等
                        Request request = chain.request().newBuilder()
                                .addHeader("os", "android")
                                .addHeader("version", "1.o")
                                .build();

                        Response response = chain.proceed(request);
                        //后置处理
                        return response;
                    }
                }).addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {

                        Request.Builder builder = chain.request().newBuilder();
                        Request request=builder.post(new UploadRequestBody(new UploadRequestBody.ProgressListener() {
                            @Override
                            public void progress(String progress, long contentLength, long currentWrite) {
                                System.out.println("progress--->>>:" + progress + "contentLength:" + contentLength + ",currentWrite:" + currentWrite);
                            }
                        },chain.request().body())).build();
                        return chain.proceed(request);
                    }
                }).build();
    }
    /**
     * 这里设置了缓存的大小和路径 默认okHttp的缓存是关闭的,需要手动开启
     */
    public void addCache() {
        okHttpClient=okHttpClient.newBuilder()
                .cache(new Cache(new File("path/cache"), 100))
                .build();
    }

    /**
     * okHttp默认不自动处理cookies
     */
    public void addCookieJar() {
        final Map<String, List<Cookie>> cookiesMap = new HashMap<>();
       okHttpClient= okHttpClient.newBuilder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
                        //返回服务器的cookie 存到本地
                        cookiesMap.put(httpUrl.host(), list);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl httpUrl) {
                        List<Cookie> cookies = cookiesMap.get(httpUrl.host());
                        return cookies == null ? new ArrayList<Cookie>() : cookies;
                    }
                })
                .build();
    }

    private void startCall(Request request) {
        startCall(request, null);
    }

    //开始请求
    private void startCall(final Request request, final ImageView imageView) {
        try {
            okHttpClient.newCall(request)
                    .enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            System.out.println("onFailure:" + e.getMessage());
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            System.out.println("threadName:" + Thread.currentThread().getName());

                            if (null != imageView) {
                                InputStream inputStream = response.body().byteStream();
                                File file = new File(imageView.getContext().getFilesDir().getPath() + File.separator + "a.png");
                                if (!file.exists()) {
                                    System.out.println("file:" + file.getPath());
                                    file.createNewFile();
                                }
                                FileOutputStream fos = new FileOutputStream(file);
                                float sum = 0l;
                                long total = response.body().contentLength();
                                byte buff[] = new byte[128];
                                int length;
                                while ((length = inputStream.read(buff)) != -1) {
                                    fos.write(buff, 0, length);
                                    sum += length;
                                    float speed = sum / total * 100;
                                    String format = (new DecimalFormat("0.00")).format(speed);
                                    String format1 = String.format("%.2f", speed);
                                    System.out.println("speed:" + speed + ",sum:" + sum + ",total:" + total + ",format:" + format + ",format1:" + format1);

                                }
                                fos.flush();
                                final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
                                imageView.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        imageView.setImageBitmap(bitmap);
                                    }
                                });
                                inputStream.close();
                            } else {
                                /**
                                 * 如果先body的string方法后调用byteStream流已经被关闭了,会导致io异常
                                 */
                                System.out.println(Objects.requireNonNull(response.body().string()));

                            }

                        }
                    });

        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }
    /**
     * 下载进度拦截
     */
    static class ProgressResponseBody extends ResponseBody {

        private ResponseBody mResponseBody;
        private ProgressResponseBody.ProgressListener mProgressListener;

        private BufferedSource mBufferedSource;

        public ProgressResponseBody(ResponseBody mResponseBody, ProgressListener mProgressListener) {
            this.mResponseBody = mResponseBody;
            this.mProgressListener = mProgressListener;
        }

        @Override
        public MediaType contentType() {
            return mResponseBody.contentType();
        }

        @Override
        public long contentLength() {
            return mResponseBody.contentLength();
        }

        @Override
        public BufferedSource source() {
            if (mBufferedSource == null) {
                mBufferedSource = Okio.buffer(getSource(mResponseBody.source()));
            }
            return mBufferedSource;
        }

        private Source getSource(Source source) {

            return new ForwardingSource(source) {

                long totalSize = 0L;
                long sum = 0L;

                @Override
                public long read(Buffer sink, long byteCount) throws IOException {

                    if (totalSize == 0) {
                        totalSize = contentLength();
                    }
                    long len = super.read(sink, byteCount);
                    System.out.println("ProgressResponseBody len:"+len);
                    sum += (len == -1 ? 0 : len);
                    System.out.println("ProgressResponseBody sum:"+sum);
                    double speed = (sum+0.0) / totalSize * 100;
                    System.out.println("ProgressResponseBody speed:"+speed);
                    String format = (new DecimalFormat("0.00")).format(speed);
                    mProgressListener.progress(format, totalSize, sum);
                    return len;
                }
            };


        }
        public interface ProgressListener {
            void progress(String progress, long contentLength, long currentWrite);
        }
    }

    //上传进度拦截器
    private static class UploadRequestBody extends RequestBody {

        private ProgressListener progressListener;
        private RequestBody requestBody;

        public UploadRequestBody(ProgressListener progressListener, RequestBody requestBody) {
            this.progressListener = progressListener;
            this.requestBody = requestBody;
        }


        @Override
        public MediaType contentType() {
            return requestBody.contentType();
        }

        @Override
        public void writeTo(BufferedSink bufferedSink) throws IOException {
            System.out.println(">>>>>");
            CountSink countSink = new CountSink(bufferedSink);
            BufferedSink buffer = Okio.buffer(countSink);
            requestBody.writeTo(buffer);
            buffer.flush();


        }

        @Override
        public long contentLength() throws IOException {
            return requestBody.contentLength();
        }

        class CountSink extends ForwardingSink {
            long byteWrite;

            public CountSink(Sink sink) {
                super(sink);
            }


            /**
             * @param source
             * @param byteCount 缓冲区大小
             * @throws IOException
             */
            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                System.out.println("write>>>>>");
                byteWrite += byteCount;
                float speed = byteWrite / contentLength() * 100;
                String format = (new DecimalFormat("0.00")).format(speed);
                progressListener.progress(format, contentLength(), byteWrite);
            }


        }

        public interface ProgressListener {
            void progress(String progress, long contentLength, long currentWrite);
        }
    }
}

二.原理分析

1.okHttp3中的构建器

构建者模式是设计模式中的创建者中的一种,当我们的对象的构建比较复杂,可以为对象添加不同的功能展示时,我们一般会使用构建者模式,我们的okhttp3的创建过程就是一个通过构建器模式的创建的,我们一般会new一个okHttpBuilder然后为其添加各种拦截器、超时等。当然,如果你不通过它来创建,okHttp3也会给你一个默认的builder参数:

public OkHttpClient() {
    this(new Builder());
}


public Builder() {
    dispatcher = new Dispatcher();
    protocols = DEFAULT_PROTOCOLS;
    connectionSpecs = DEFAULT_CONNECTION_SPECS;
    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;
}

我们通过一个简单的例子来表述下okHttpClient和其builder之间的关系:

static class Design {

    House house;
    Floor floor;

    Window window;


    public Design() {
        this(new Builder()); //使用默认参数
    }

    //build的参数
    Design(Builder builder) {
        this.house = builder.house;
        this.floor = builder.floor;
        this.window = builder.window;
    }

    /**
     * 获取对象的builder构建起对象
     *
     * @return
     */
    public Builder newBuilder() {
        return new Builder(this);
    }

    static class Builder {
        House house;
        Floor floor;
        Window window;

        //1.默认参数
        public Builder() {
            house = new House();
            floor = new Floor();
            window = new Window();
        }

        //2.外部传过来的
        public Builder(Design design) {
            house = design.house;
            floor = design.floor;
            window = design.window;
        }

     

        //3,修改图纸
        public Builder buildWindow(Window window) {
            this.window = window;
            return this;
        }
        //4.通过该方法生成一个新的图纸
        public Design builder() {
            return new Design(this);
        }
    }

}

static class House {

}

static class Floor {

}

static class Window {

    public String windowColor = "red";

}

@Test
public void testDefaultBuilder() {

    //使用默认的构造器
    Design design = new Design();
    System.out.println(design);
    System.out.println(design.window.windowColor);
    Window window = new Window();
    window.windowColor = "green";

    Design design2 = design.newBuilder().buildWindow(window).builder();
    System.out.println(design2.window.windowColor);
}

上面是一个设计师设计房子的图纸,由于设计时需要绘制房子、窗户、地板等,所以我们提供了房子的构建者,当然构建者构建出来的对象当然是设计图纸。所以构建者的作用有:1.生成默认图纸对象;2.支持外部传入设计对象;3.支持修改当前设计图纸,并通过构建后返回生成新的图纸;那设计师的作用是:提供默认图纸,当然是通过上面的默认构造器生成;2.支持获取当前图纸的构造器,这样就可以修改当前图纸并且生成新的图纸对象;所以我们的图纸的创建就完全依赖于builder来创建,我们新建的默认图纸或为图纸增加新的功能都需要依赖builder实现。

其实在okHttp中的源码也是这样,我们创建一个默认okHttpClient就是new,如果要通过builder创建,就需要先创建一个builder或者通过okHttpClient.newBuilder之后在创建一个新的okHttpClient.

2.okHttp3中的责任链

责任链模式是设计模式中的行为型设计模式,它是由多个对象都有机会处理请求,并且形成链条传递,直到有人处理请求。下面我们通过一个简单职场的例子来说明:比如小王请假,会向主管申请,主管有权限就批准了,但是他想升职,主管批复后,还得向经理提交,经理提交后才可以,如果要加薪经理提交后还得向老板申请,这样就形成了一个责任链,在链条上的每个人都可以处理请求,但是由于请求的类别不同,处理的权限不同,就会向上一级提交请求,最终顶层执行后会返回给用户一个提交结果。

那我们用代码的形式表述如下:

    public void testChain() {

        Boss boss = new Boss(null);
        Manager manager = new Manager(boss);
        Head head = new Head(manager);

        Request request=new Request();
        request.request="请假";
        System.out.println(head.handlerRequest(request).response);
//        head.handlerRequest("升职");
//        head.handlerRequest("加薪");
    }

    //抽象处理请求
    static abstract class Handler {
        public abstract Response handlerRequest(Request request);//

        Handler nextHandler;//上一级领导

        public Handler(Handler nextHandler) {
            this.nextHandler = nextHandler;
        }
    }

    class Request {
        public String request;
    }

    static class Response {
        public String response;
    }

    /**
     * 主管
     */
    static class Head extends Handler {

        public Head(Handler nextHandler) {
            super(nextHandler);
        }

        @Override
        public Response handlerRequest(Request request) {

            if (request.request.equals("请假")) {
                Response response = new Response();
                response.response = "主管批复了";
                return response;
            } else {
                //上一级领导处理
                System.out.println("主管未知指令 转交给上级");
                return nextHandler.handlerRequest(request);
            }
        }
    }

    static class Manager extends Handler {

        public Manager(Handler nextHandler) {
            super(nextHandler);
        }

        @Override
        public Response handlerRequest(Request request) {

            if (request.request.equals("升职")) {
                Response response = new Response();
                response.response = "经理批复了,成功";
                return response;
            } else {
                System.out.println("经理未知指令 转交给上级");
                return nextHandler.handlerRequest(request);
            }
        }
    }

    static class Boss extends Handler {

        public Boss(Handler nextHandler) {
            super(nextHandler);
        }

        @Override
        public Response handlerRequest(Request request) {

            Response response = new Response();
            if (request.request.equals("加薪")) {
                response.response = "老板批复了,成功";
            } else {
                response.response = "老板未知请求";
            }
            return response;
        }
    }

}

可以看到我们的链条的连接需要手动去关联下,在okHttp中,他使用了是一个接口Chain的接口,这个接口链条持有了请求和响应,拦截器则是返回了响应,类关系如下图:

拦截调用关系如下图所示:每个拦截器都可以直接返回结果,也可以通过chain.proceed(request)方法将请求传递给下一个拦截器,并获取处理接结果。

我们用代码模拟下okHttp中的责任链的变形与实现:

/**
     * 类比拦截器
     */
public interface Interceptor {
    String intercept(Chain chain);

    /**
         * 拦截器的链条,每个拦截器都在链条上,并且每个拦截器可以直接返回结果或者
         * 通过下一个链条来获取结果
         */
    interface Chain {
        String request();

        String proceed(String request);

    }
}

/**
     * 拦截器1
     */
class I1 implements Interceptor {

    @Override
    public String intercept(Chain chain) {
        System.out.println("I1 intercept EXE");
        String response=((RealInterceptorChain)chain).proceed(chain.request());//将当前请求传过去 让链条下端处理
        System.out.println("I1 intercept EXE after");
        return response;
    }
}

/**
     * 拦截器2
     */
class I2 implements Interceptor {

    @Override
    public String intercept(Chain chain) {
        System.out.println("I2 intercept EXE");
        //            String response=((RealInterceptorChain)chain).proceed(chain.request());
        System.out.println("I2 intercept EXE after");
        return "response";
    }
}

public final class RealInterceptorChain implements Interceptor.Chain {

    private final int index; //当前的index
    private final String request;
    private final List<Interceptor> interceptors; //拦截器列表

    public RealInterceptorChain(int index, String request, List<Interceptor> interceptors) {
        this.index = index;
        this.request = request;
        this.interceptors = interceptors;
    }


    @Override
    public String request() {
        return request;
    }

    /**
         * 执行流程
         *  1.生成下一个拦截器(这里非常的巧妙的使用创建一个RealInterceptorChain作为下一个拦截器,
         *  并且这个对象的index是index+1的,当前的拦截器如果传递链条,又会执行到这个对象的proceed方法时,index就会变成index+1,
         *  依次往后又创建,这样index就会不停的+1直到等于列表大小)
         *  2.获取当前拦截器
         *  3.执行当前拦截器的拦截方法,并传入下一个拦截器;
         * @param request
         * @return
         */
    @Override
    public String proceed(String request) {
        System.out.println("index:"+index);
        if (index >= interceptors.size()) throw new AssertionError();
        //通过它来绑定链条上的关系
        RealInterceptorChain nextInterceptor = new RealInterceptorChain(index + 1, request, interceptors);


        //调用当前端或者认为它是调用下一段,因为如果是上一段(index+1)调用的,就可以理解为下一段
        Interceptor interceptor = interceptors.get(index);

        String response = interceptor.intercept(nextInterceptor);

        return response;
    }
}

@Test
public void testChain() {

    List<Interceptor> interceptors=new ArrayList<>();
    interceptors.add(new I1());
    interceptors.add(new I2());
    RealInterceptorChain realInterceptorChain=new RealInterceptorChain(0,"request",interceptors);
    realInterceptorChain.proceed("request");

}

当我们调用realInterceptorChain.proceed("request")时,它的执行流程是:

1.处理当前拦截器的拦截方法,传入(index+1)的RealInteceptorChain链条对象->2.当前拦截器的拦截方法会向链条的下一段传递,而这个下一段,并非时I2,而是我们的RealInteceptorChain,它的proceed的处理方法也是调用列表中的下一段(index+1)拦截方法而已,因为它的index是上传传递过来的index+1->(1-2)步骤循环直到拦截列表结束或者拦截器不通过RealInteceptorChain来传递到下端。


3.请求流程

1.Call的执行流程

Call是个抽象类,它的请求在实现类RealCall中执行,异步请求执行,将请求包装成AsyncCall,并添加到分发器的请求队列中,AsyncCall是RealCall的内部类,它继承自NameRunnable,当线程池执行这个AsyncCall时,会执行他的run方法,而它的run方法就是调用AsyncCall的execute方法,请求执行完后,调用dispatcher分发器的移除运行队列中的这个call。同步执行则是直接把他加入到运行队列中,并阻塞当前线程,直到有结果或异常。

@Override public Call newCall(Request request) {
  return new RealCall(this, request, false /* for web socket */);
}

在调用call的execute()方法,我们跟下这个方法:

//同步执行
@Override public Response execute() throws IOException {
synchronized (this) {
    if (executed) throw new IllegalStateException("Already Executed");
    executed = true;
}
captureCallStackTrace();
try {
    client.dispatcher().executed(this);//放到队列中去
    Response result = getResponseWithInterceptorChain();//执行操作
    if (result == null) throw new IOException("Canceled");
    return result;
} finally {
    client.dispatcher().finished(this); //完成后移除
}
}

private void captureCallStackTrace() {
    Object callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()");
    retryAndFollowUpInterceptor.setCallStackTrace(callStackTrace);
}

//异步执行
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
    if (executed) throw new IllegalStateException("Already Executed");
    executed = true;
}
captureCallStackTrace();
//包裹新的异步call并放到分发器的队列中去 会执行Dispatcher中的enqueue的方法
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;

    AsyncCall(Callback responseCallback) {
        super("OkHttp %s", redactedUrl());
        this.responseCallback = responseCallback;
    }

    String host() {
        return originalRequest.url().host();
    }

    Request request() {
        return originalRequest;
    }

    RealCall get() {
        return RealCall.this;
    }

    @Override protected void execute() {
        boolean signalledCallback = false;
        try {
            Response response = getResponseWithInterceptorChain();
            if (retryAndFollowUpInterceptor.isCanceled()) {
                signalledCallback = true;
                responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
            } else {
                signalledCallback = true;
                responseCallback.onResponse(RealCall.this, response);
            }
        } catch (IOException e) {
            if (signalledCallback) {
                // Do not signal the callback twice!
                Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
            } else {
                responseCallback.onFailure(RealCall.this, e);
            }
        } finally {
            client.dispatcher().finished(this);
        }
    }
}
public abstract class NamedRunnable implements Runnable {
    protected final String name;

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

    @Override public final void run() {
        String oldName = Thread.currentThread().getName();
        Thread.currentThread().setName(name);
        try {
            execute();
        } finally {
            Thread.currentThread().setName(oldName);
        }
    }

    protected abstract void execute();
}

2.任务分发器Dispatch

异步执行:根据当前call请求数量是否大于64和同一个host请求是否大于5来决定加入到异步等待队列还是执行队列

  private int maxRequests = 64; //最大请求数量
  private int maxRequestsPerHost = 5;
  synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
          runningAsyncCalls.add(call);
            //线程池执行call,也就是会执行NamedRunnable的run方法-》AsyncCall的execute方法
          executorService().execute(call);
        } else {
            //放到等待队列中去
          readyAsyncCalls.add(call);
        }
  }

同步执行:直接将call加入到同步运行队列

synchronized void executed(RealCall call){
    runningSyncCalls.add(call); 
}

4.流程总结

下面我用一张图来对流程做个总结: