OKHttp分发器源码分析(两个版本)

本文主要介绍OKHttp这一Android常用网络请求框架,提及Google在Android4.4后将底层实现替换为OKHttp,Retrofit也基于其封装。重点对OKHttp 3.10.0和4.9.3两个版本的分发器进行源码追溯与分析,比较了执行流程,还简单提到分发器中的线程池。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】简介

OkHttp是当下Android使用最频繁的网络请求框架,由Square公司开源。 Google在Android4.4以后开始将源码中的HttpURLConnection底层实现替换为0KHttp,同时现在流行的Retrofit框架底层同样是使用OKHttp的。

我们将了解下OKHttp的源码,但是不同的版本源码会有一些差异,等下我会大概说一下3.10.04.9.3版本的不同之处


【2】简单使用(略谈)

大家应该都用过OKHttp,只是你们自己可能都不知道,因为我们项目中经常使用的是像Retrofit这样的网络框架,但其实Retrofit是基于OKHttp进行的再次封装,将返回的结果等进行了一些更加人性化的封装,更便于我们开发使用。

①使用流程图如下:

在这里插入图片描述

②使用代码如下:

//1
        OkHttpClient okHttpClient = new OkHttpClient();
        
        //2
        Request request = new Request.Builder()
                .url("www.baidu.com")
                .build();
        //3
        Call call = okHttpClient.newCall(request);
        
        //4异步请求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {

            }
        });
        
        //或者同步请求
        try {
            Response response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }

其实看了这个发现OKHttp重要的还是分发器和拦截器,那么下面我们就来讲一下什么是分发器、拦截器,他们有什么用,是怎么工作的。


【3】分发器(两个版本)

Dispatcher 分发器就是来调配请求任务的,内部会包含一个线程池(异步任务才会用到)。可以在创建 OkHttpClient 时,传递我们 自己定义的线程池来创建分发器。下面我们跟着源码追一下吧,我们看异步的,同步的可以自行查看比较简单。

一、OKHttp 3.10.0版本的分发器源码追溯

①从这里进去
在这里插入图片描述
②Call只有一个默认实现类RealCall
在这里插入图片描述

③进到RealCallenqueue中,发现要去到dispatcherenqueue
在这里插入图片描述

④分发器中的enqueue
在这里插入图片描述
分发器异步任务的时候有两个队列

  • runningAsyncCalls
  • readyAsyncCalls

running当前任务数小于规定的max值(默认64)(考虑到手机压力)
running队列里面正在访问的host和当前host相同的任务不能超过5个(减少服务器压力)

当正在执行的任务未超过最大限制64,同时 runningCallsForHost(call) < maxRequestsPerHost 同一Host的请求 不超过5个,则会添加到正在执行队列,同时提交给线程池直接执行。否则先加入等待队列。

⑤线程池执行应该是找到AsyncCall的run方法
在这里插入图片描述

但他没有run方法,而且继承的也不是Runable对象,我们看下NamedRunnable到底是个什么东西


在这里插入图片描述
原来如此,有个抽象的execute方法在run里面执行,所以线程池就会执行AsyncCallexecute方法了


在这里插入图片描述
try和catch先不管看到finally,会执行finished方法


在这里插入图片描述
将这个任务从runningAsyncCalls中移除,然后命中if语句,进入promoteCalls


在这里插入图片描述
遍历readyAsyncCalls中的任务,根据判断的规则将任务加入到runningAsyncCalls中然后调用线程池进行执行。

现在我们想想是不是分发器我们已经走完一遍了?不是要从分发器到拦截器吗?根据我们上面的整体流程图应该是这样的,那我们什么时候进入到拦截器的呢?其实是在execute方法的时候:

在这里插入图片描述

二、OKHttp4.9.3版本的源码分析


在这里插入图片描述

②又是这个接口还是只有RealCall这个默认实现类
在这里插入图片描述

③进入到RealCallenqueue
在这里插入图片描述

④来到dispatcherenqueue方法中
在这里插入图片描述
这里已经是不一样的了,这里不再判断,而是直接将任务加入到readyAsyncCalls中,然后调用promoteAndExecute

在这里插入图片描述
遍历,然后根据上面相同的条件,是否将任务加入到runningAsyncCalls中,另外多了一个队列executableCalls

在这里插入图片描述
然后遍历执行executableCalls队列中的任务

在这里插入图片描述
⑨还是要来到dispatcherfinished方法
在这里插入图片描述

这个版本的源码我没有详细讲解,但是你们应该都看得懂。跟3.10.0版本的有一些区别,但是也有很多相似的地方

三、两个不同版本的执行流程比较:

①3.10.0版本的流程

3.10.0版本的分发器异步执行流程

②4.9.3版本的流程

4.9.3版本的分发器异步执行流程

四、分发器中的线程池

这里由于篇幅,不再详细说明,这里线程池的队列用的无界队列SynchronousQueue
在这里插入图片描述
核心线程数为0,最大线程数为Integer.MAX_VALUE
实现了一个最大并发量的线程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值