android网络请求框架(android 网络请求库)

http://www.itjxue.com  2023-02-18 03:50  来源:未知  点击次数: 

网络请求框架-OkHttp原理解析

okhttp是square公司贡献的一个处理网络请求的开源框架,是目前Android开发使用最广泛的一个网络框架,从Android4.4开始,httpURLconnection的底层实现采用的就是okhttp。内部实现就是利用java基础,对socket进行封装,实现http通信。最重要的两个关键点就是分发器和5个拦截器。

分发器 就是内部维护队列和线程池,完成请求分配,总结就是用于对异步任务加入队列管理,然后判断条件,控制数量,加入线程池执行异步请求任务。

五个默认拦截器 就是利用责任链模式对网络请求进行层层处理,完成整个请求过程,简单总结如下。

1.桥接拦截器对用户发出的请求添加缺少的请求配置字段,比如keep-alive等

2.缓存拦截器就是查询有没有符合判断条件的已缓存的网络请求,执行复用,直接返回response

3.连接拦截器就是创建请求,加入连接器 或者访问连接池,根据条件判断,是否能怼已创建的tcp请求进行复用

4.请求服务器拦截器就是对scoket进行操作,请求网络访问服务器,返回response,

5.重试和重定向拦截器就是对返回的response进行code判断,决定是否要重试或者重定向操作。

1.支持http2.0版本,并且允许对同一主机的所有请求共享一个套接字

2.即使不是http2.0版本,通过连接池,减少请求延迟

3.默认使用Gzip 压缩数据

4.响应缓存,避免重复请求网络

最简单的http请求案例

1.利用建造者模式构建okHttpClient实例对象,构建过程中可以动态配置参数,请求时间,响应时间,缓存信息等。

2.创建Request对象,设置请求方式,链接地址,参数等信息。

3.把request对象,传给client,通过newCall函数,得到RealCall对象。

4.RealCall 分为同步和异步执行

5.同步执行时,分发器只是做个记录,把请求任务加到队列中,然后直接通过拦截器访问服务器,返回response。

6.异步执行

6.1先对异步任务进一步封装,把任务放到AsyncCall对象中

2.分发器 把 封装后的异步任务 添加到等待运行的队列中

7.getResponseWithInterceptorChain 通过拦截器,获取response

okhttp 默认提供5个拦截器 重试重定向拦截器,桥接拦截器,缓存拦截器,连接拦截器,访问服务器拦截器。还可以自定义拦截器。

自定义拦截器分为应用拦截器(通过addInterceptor 添加)和网络拦截器(通过addNetworkInterceptor拦截)

拦截器采用责任链的设计默认,让请求者和处理者解耦,最终请求从前往后,响应从后往前。

首先先判断用户是否取消了请求,如果没有取消,就把请求交个桥接拦截器。

在获得响应结果response的时候根据响应码,判断是否需要重试或者重定向, 重试不限制次数,重定向最多20次 ,如果需要重试或者重定向,那么会再一次重新执行所有拦截器。

有如下几种情况不会重试:IO异常,线路异常,配置client实例时配置不允许重试,协议异常,证书异常等等。

先获取用户发送的请求,判断条件用户是否已经配置过请求头字段,若用户没有配置,则将http协议必备的请求头字段补齐,比如Content-Type,Content-Length等,然后交给下一个拦截器。

在获得响应结果response之后,调用保存cookie的接口(也可以在配置client的时候,设置cookjar进行cookie回调数据),并且解析gzip数据

获取结果之后,对cookie进行保存,对返回的数据进行gzip解压

就是根据缓存策略从缓存中查找是否有合适的缓存response,如果有合适的缓存,直接返回给请求任务,不在继续执行后面的拦截器。

获得响应结果response后,根据条件判断,决定是否要缓存。

维护一个连接池,负责对连接的服务。在把请求交给下一个拦截器之前。会先在连接池中找到一个合适的连接(满足适配条件相同,并且没有正在被使用)或者新建一个连接,并且接入连接池,获得对应的socket流,把请求交给下一个拦截器。获得response结果后不会进行额外的处理。

连接池, 也称之为对象池,主要用来存放request请求连接,内部维护了一个LinkedQueue队列用来存放请求。在添加新的请求对象时,都会执行一个周期性任务,用以对连接池进行清理操作。

1.队列长度超过5,清理最近未被使用连接,LRE算法

2.存储的连接,5分钟未被复用,清理

拿到上一个拦截器返回的请求,真正的与服务器进行通信,向服务器发送数据,解析读取响应的数据,返回给上一个拦截器。

1.创建request =OkHttpClient=RealCall()

2.同步执行 ,分发器添加同步任务,执行拦截器,访问服务器,返回reponse,触发异步分发流程。

3.异步执行 ,封装任务= AsyncCall ,实现runnable接口。添加任务到异步任务等待队列,执行分发任务,判断异步任务是否能加入正在执行的异步任务队列,满足两个条件

同时执行的异步任务数量不得大于64个

对同一个主机的访问任务,最多不得大于5个

4.加入正在执行的异步任务队列,通过线程池执行任务,经过5个默认拦截器访问服务器,返回response,执行异步任务分发。

分发器工作 分为同步任务和异步任务两种

同步任务 就是把任务加入同步任务队列,加个标记,执行结束之后,触发异步任务的分发操作。

异步任务 先封装任务到asyncCall对象,实现了runnable接口。把任务加入等待执行队列,执行分发操作。

先遍历等待任务队列,判断是否符合加入正在运行的异步任务队列,要同时满足两个条件。

同时执行的异步任务数量不得大于64个

对同一个主机的访问任务,最多不得大于5个

当满足条件后,从等待队列中删除任务,把任务加入正在执行的队列中,通过自定义的线程池,执行任务,任务执行结束后,再次执行分发操作。

拦截器采用了责任链设计默认,让请求者和执行者解耦,请求者只需要将请求发给责任链即可,无需关心请求过程和细节。okHttp 默认有5个拦截器,重试重定向拦截器,桥接拦截器,缓存拦截器,连接拦截器,请求服务拦截器。工作细节参考上面拦截器原理分析部分

1.位置的关系,应用拦截器 放在责任链最顶端,网络拦截器放在责任链倒数第二的位置。所以应用拦截器 最先拦截,最后响应,网络拦截器 倒数第二拦截,第二响应。如果打印请求日志的情况,应用拦截器打印的是用户请求信息,经过重试重定向,桥接,缓存,链接 等拦截器的层层包装,网络拦截器打印的是实际请求的信息。

2.应用拦截器一定会被执行,网络拦截器不一定被执行。

利用连接池,缓存所有的有效连接对象。

清理机制:垃圾连接

1.超过5分钟没有用过的链接

2.超过5个闲置链接后,从最久闲置的链接开始执行清理(LRU)

android 五大应用开发框架是什么?

1.Linux Kernel

2.Android Runtime

3.Libraries

4.Application Framework

5.Applications

andbase框架:

1.andbase中包含了大量的开发常用手段。

如网络下载,多线程与线程池的管理,数据库ORM,图片缓存管理,图片文件下载上传,Http请求工具,常用工具类(字符串,日期,文件处理,图片处理工具类等),能够使您的应用在团队开发中减少冗余代码,很大的提高了代码的维护性与开发高效性,能很好的规避由于开发疏忽而导致常犯的错误。

2.andbase封装了大量的常用控件。

如list分页,下拉刷新,图片轮播,表格,多线程下载器,侧边栏,图片上传,轮子选择,图表,Tab滑动,日历选择器等。

3.强大的AbActivity,您没有理由不继承它。

继承它你能够获得一个简单强大可设置的操作栏,以及一系列的简单调用,如弹出框,提示框,进度框,副操作栏等。

4.提供效率较高图片缓存管理策略,使内存大幅度节省,利用率提高,效率提高。

程序中要管理大量的图片资源,andbase提供简单的方法,几步完成下载与显示,并支持缩放,裁剪,缓存功能。

5.封装了大量常见工具类。

包括日期,字符,文件,图片等各种处理函数, 多而全。

6.用andbase大量减少handler的使用,而采用回调函数,代码更整洁。

handler会产生大量代码,并且不好维护,andbase对handler进行了封装。

7.简单轻量支持注解自动建表的ORM框架(支持一/多对多的关联操作)。

写sql,建表,工作量大,andbase提供更傻瓜异步增删改查工具类。

8.异步请求http框架,网络请求标准化,支持文件上传下载,get,post,进度显示。

Android Retrofit详解

Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装,网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装

1.添加Retrofit库的依赖:

后面三个是可选的,分别是数据解析器和gson,以及rxjava支持的依赖

2.创建 用于描述网络请求 的接口

Retrofit将 Http请求 抽象成 Java接口:采用 注解 描述网络请求参数 和配置网络请求参数

3.创建Retrofit实例

4.发送请求

请求分为同步请求和异步请求

response.body()就是Reception对象,网络请求的完整 Url =在创建Retrofit实例时通过.baseUrl()设置 +网络请求接口的注解设置(下面称 “path“ )

整合的规则如下:

上面我们用了@GET注解来发送Get请求,Retrofit还提供了很多其他的注解类型

1.@GET、@POST、@PUT、@DELETE、@HEAD分别对应 HTTP中的网络请求方式

2.@HTTP替换@GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展

具体使用:通过属性method、path、hasBody进行设置

1.@FormUrlEncoded

表示发送form-encoded的数据,每个键值对需要用@Filed来注解键名,随后的对象需要提供值。

2.@Multipart

表示发送form-encoded的数据(适用于 有文件 上传的场景),每个键值对需要用@Part来注解键名,随后的对象需要提供值。

1.@Header @Headers

添加请求头 添加不固定的请求头

2.@Body

以 Post方式 传递 自定义数据类型 给服务器,如果提交的是一个Map,那么作用相当于 @Field,不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单,如:

3.@Field @FieldMap

发送 Post请求 时提交请求的表单字段,与 @FormUrlEncoded 注解配合使用

4.@Part @PartMap

发送 Post请求 时提交请求的表单字段,与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 有文件上传 的场景,与 @Multipart 注解配合使用

5.@Query和@QueryMap

用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)

如:url = ,其中,Query = cate

配置时只需要在接口方法中增加一个参数即可:

6.@Path

URL地址的缺省值

7.@Url

直接传入一个请求的 URL变量 用于URL设置

Android网络篇(四)—— 自己动手封装一个属于自己的网络请求框架

网络请求框架算是android体系当中一个比较重要的部分,在android历史中关于网络的演进也经历了几个阶段,到目前为止,比较通用的网络请求框架就是OkHttp + Retrofit +RxJava+Gson,当然,关于这个组合使用网上也有很多,但是,那个毕竟是别人的东西,大部分时候只有适合自己的才是最好的,所以,自己封装一个网络请求框架就显得比较重要了,废话不多说,直接动手开干。

网络请求框架封装大概流程如下:

当然,在基本流程之外还有一些辅助类:

然后在我们的Application里面进行初始化设置

当然,别忘记在清单文件里面设置网络权限哦

最后需要注意的是,千万别导入错误的包,我引入的依赖为

最后看下效果

在这里我只测试了Get请求(使用Path形式)和Post请求(带参以RequestBody方式提交),其他的大家可以根据自己的需求自行测试。

Android Okhttp/Retrofit网络请求加解密实现方案

比较安全的方案应该是AES+RSA的加密方式。具体如下图所示。

为什么要这样做呢?

1、RSA是非对称加密,公钥和私钥分开,且公钥可以公开,很适合网络数据传输场景。但RSA加密比较慢,据说比AES慢100倍,且对加密的数据长度也有限制。

2、AES是对称加密,加密速度快,安全性高,但密钥的保存是个问题,在网络数据传输的场景就很容易由于密钥泄露造成安全隐患

3、所以,AES+RSA结合才更好,AES加密数据,且密钥随机生成,RSA用对方(服务器)的公钥加密随机生成的AES密钥。传输时要把密文,加密的AES密钥和自己的公钥传给对方(服务器)。对方(服务器)接到数据后,用自己的私钥解密AES密钥,再拿AES密钥解密数据得到明文。这样就综合了两种加密体系的优点。

4、除上面说的外,还可以加签名,即对传输的数据(加密前)先做个哈希,然后用自己的RSA私钥对哈希签名(对方拿到自己的公钥可以验签),这样可以验证传输内容有没有被修改过。

就java来说,加密的输入和输出都是字节数组类型的,也就是二进制数据,网络传输或本地保存都需要重新编码为字符串。推荐使用Base64。Android 有自带的Base64实现,flag要选Base64.NO_WRAP,不然末尾会有换行影响服务端解码。

Android中Base64加密

总而言之,这些不同语言都有实现库,调用即可,关键是参数要一致,具体还需要和后台联调一下。

rsa加解密的内容超长的问题解决

现在说到网络框架,应该毫无疑问是Retrofit了。上面说的加密方案说到底还是要在网络请求框架内加上,怎么做入侵最小,怎么做最方便才是重点。

1、坑定不能直接在接口调用层做加密,加参数,这样每个接口都要修改,这是不可能的。

2、ConverterFactory处理,这也是网上可以搜到的很多文章的写法,但我觉得还是有入侵。而且有点麻烦。

3、OkHttp添加拦截器,这种方法入侵最小(可以说没有),实现呢也非常优雅。

下面的实现,网上也找不到多少可以参考的文章,但不得不说,OkHttp的封装和设计真的很好用,所见即所得。看下源码,就知道该怎么用了,连文档都不用查。

主要注意点:

0、和接口无关的新加的数据放在请求头里。

1、该close的要close,不然会内存泄漏。

2、新旧Request和Response要区分好,新的要替换旧的去传递或返回。

3、要对response.code()做处理,只有在和后台约定好的返回码下才走解密的逻辑,具体看自己的需求,不一定都是200。

Android使用OKGO的坑

首次项目使用okgo网络请求框架,碰到一个非常坑的bug,这里做个记录。

每次A表单页面提交数据请求,成功之后然后跳转到B页面之后接受到数据马上请求数据,请求的socket会被close,请求到一半,没有返回直接被close。这个bug还会在页面收到通知之后连续两次请求网络出现,这让我这个菜逼非常苦恼,一直找不到完美的解决办法,最后只能以一个非常笨的方式解决一下。

我做了个开关,isGetData=false;在请求成功之后开关变为true,否则就做个定时任务

mHandler.postDelayed(newRunnable() {

@Override

public voidrun() {

if(!isGetData)

initUserInfo();//异步获取用户信息

}

},200);

这样暂时解决这个问题,但是治标不治本,后来终于找到解决方法,原来是因为访问https出现的bug,做个记录。

OkHttpClient client =newOkHttpClient.Builder()

.protocols(Collections.singletonList(Protocol.HTTP_1_1))

.build();

即可,如果是okgo则如下

(责任编辑:IT教学网)

更多

推荐SQL Server文章