Android网络请求优化及离线上传封装

format,png

 0455ffcf92122c7a8d86364d3ab9bf6e.gif 

本文字数:11171

预计阅读时间:28分钟

前言

在android开发中,无论是去解决网络请求中遇到的问题,还是优化网络请求的效率,都离不开最根本的网络传输协议(http和tcp等),所以本文的第一部分是对网络协议相关的基础知识进行讲解。掌握了必备的基础知识之后,接下来的第二部分,会对android中使用最广泛的网络请求框架okhttp进行分析,这款框架不仅对基础的网络请求逻辑进行了封装,还尽善尽美的替我们做好了几乎每一件可以去优化的事情,如果能很好的理解并使用它,我相信大部分网络请求相关的问题都可以很好的得到解决。本文的最后部分,想说一说我是如何使用kotlin反射对离线数据上传进行封装的。

网络传输协议

网络传输协议大概分为4层(图片来自于极客教程):

5f6718bafaac7832d7fbb2070cefa9e6.png

(图1)

即链路层、网络层、传输层、应用层。其中,链路层协议是用来在各个物理节点(主机、交换机、路由器)之间传输的协议,会把网络层的ip数据包和mac地址封装成帧,通过mac地址来定位传输以帧为单位的数据。网络层协议是通过ip地址进行路由选择。这两层的协议基本上不用我们操心,我们主要来看一下传输层和应用层协议。

TCP和UDP协议

TCP和UDP都是传输层协议,不关心数据的格式,只负责传输,把上层的数据分割成一段一段的去传输。TCP协议是可靠的,有连接的,顺序发送数据,顺序接收(收到数据之后会确认,得到确认之后才会继续发送)。UPD是不可靠的,无连接的,顺序发送数据,乱序接收(不需要确认,不关心有没有收到)。

TCP如何实现可靠传输

TCP传输的每一段数据都会被装在一个TCP头里,头的内容包括接收方端口号、序列号、标志位、确认码

三次握手:TCP需要经过三次握手创建连接: 第一次握手:客户端首先向服务端发送一个标志位为SYN的数据段,它的序列号为X,表示要创建连接 第二次握手:服务端收到客户端的SYN数据段,会向客户端回应一个标志位为ACK的确认数据段,它的序列号为Y,还会附带一个确认号X+1,X+1表示是对序列号为X数据段的确认 第三次握手:客户端再向服务端回应一个标志位为ACK的确认数据段,它的序列号为X+1,确认号为Y+1,服务端收到后就完成了TCP连接的创建

为什么要使用三次握手?一个原因是可以协商双方的初始序列号,后续的传输都可以通过初始序列号偏移和确认。另外一个原因是可以防止服务端资源的浪费,比如一次握手就建立了连接,服务端开始向客户端发送数据,这段数据可能因为某种原因没有到达客户端,客户端误以为连接失败便不再接收数据,此时服务端依然在向客户端发送数据,造成资源的浪费。

有了三次握手创建的可靠连接,交换了初始序列号,后续通过确认号确认收到数据,如果没有收到就重新发送,由此便实现了可靠的数据传输

四次挥手:四次挥手用于安全的关闭连接 第一次挥手:客户端向服务端发送一个标志位为FIN的数据段,表示要断开连接 第二次挥手:服务端收到FIN数据段,向客户端发送一个标志位为ACK的确认数据段,然后开始发送最后的数据 第三次挥手:服务端发送完所有数据后,向客户端发送一个标志位为FIN的数据段 第四次挥手:客户端向服务端再发送一个标志位为ACK的确认数据段,连接关闭

HTTP协议

http即超文本传输协议,是应用层协议,它把应用层的各种类型数据封装为http报文,使用tcp协议分割为报文段进行传输。http报文分为两种,请求报文与响应报文。

请求报文的组成包括:请求行、头部字段、实体数据请求行的组成为:请求方式、url地址、http协议版本号

响应报文的组成包括:状态行、响应头、响应体状态行的组成为:状态码和http协议版本

常用请求方式有五种:GET:从服务端查询数据,请求报文里不包含实体数据 POST:向服务端提交数据,请求报文中包含实体数据 HEAD:获取响应报文的头部字段 PUT:直接向服务器写入或更新资源 DELETE:从服务器删除资源

http协议版本:http1.0:每次请求都需要重新建立tcp连接,连接无法复用,有性能问题

http1.1:引入了长连接keep-alive,各个请求是串行处理的,一个请求出现超时,其他请求就会被阻塞

http2.0:

  1. 使用二进制格式传输,1.x版本都是基于文本的

  2. 多路复用,一个tcp连接可以同时支持多个http请求,提升了效率

  3. header优化:header进行了压缩且会进行缓存

  4. 支持服务端向客户端push消息

OkHttp原理

OKHttp已经替我们做好了几乎所有事情,包括创建http请求报文、建立tcp连接、设置缓存等,我们只需要根据自己的需要发号施令就可以发起网络请求了。它巧妙地使用了责任链模式,使各个功能模块独立出来,各司其职,就像流水线一样,产品每经过一个加工站,装上几个零件就发往下一个站点。请求报文和响应报文就是这样的产品,经过每一个处理单元,得到最终的请求数据或响应数据。

OKHttp中的 拦截器(interceptor) 就是http报文的加工站,我们只需要理解每一个interceptor的职责就可以搞清楚它的原理了。

在使用拦截器之前,第一件事是要创建请求数据,和我们前面说的http请求报文的内容类似,包括url地址、请求方式、头部字段、实体数据:

8737a29b8adf69e8ab8d03d8539dbe0a.png


其中实体数据包括媒体类型和数据体:

833c073b26b5c89da2d31292884b608c.png

2823f7207789c7b268104c952a41617e.png

接着就是把Request依次向每一个拦截器传递,注意这个拦截顺序是不能改变的,后面会详细说。请求完成,得到响应数据之后,再依次向上传递。

具体实现:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值