Android网络部分笔记

Posted by 卢小胖 on 2020-08-05
Estimated Reading Time 6 Minutes
Words 1.7k In Total
Viewed Times

1.TCP/IP说一下

  • TCP/IP是网络协议的总称,包括了TCP\UDP\IP\HTTP\FTP等协议,大概可以分为4层:链路层,网络层,链路层,网络应用层,TCP\UDP都是传输层中的协议。
  • TCP全称传输控制协议,传输形式为数据流,是面向连接的协议,也就是说必须与 对方建立连接才能(参考TCP三次握手四次挥手)
  • UDP是用户数据报协议,传输形式为数据报,是不面向连接的。

2.HTTP/HTTPS了解多少

  • HTTP是网络协议中的网络应用层,全称超文本传输协议,HTTP协议是B/S架构,浏览器作为HTTP客户端通过URL向web服务器发送请求。
  • HTTPS可以理解为HTTP+SSL,通过ssl证书来验证服务器的身份,为浏览器和服务器之间的传输加密。
  • http因为是明文传输,所以不太安全。https因为SSL涉及加密算法,所以消耗比http多,加载会变慢。

3.HTTP断点传输

  • 在请求头中指明Range参数,一般格式Range:(unit=first byte pos)-[last byte pos]
  • 响应头中用Content-Range指示了实体的长度,一般格式:Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]

4.多线程下载大文件

首先我们要知道为什么多线程下载速度会更快?理论进程的实时网速=实时可用网络带宽,但再实际中进程拥有的带宽<=实时可用带宽。

TCP拥有一个流量探测机制,一个TCP连接遇到丢包之后速度会骤减,速度升的却很慢。总结就是单个TCP连接不稳定,需要多线程来弥补,当TCP连接更加智能稳定的时候,多线程就没有优势了。

参考:https://www.zhihu.com/question/376805151

5.HTTP2.0了解多少

目前大多版本是HTTP1.0(1996年)和1.1(1999年)
HTTP2.0有更好的web性能,更低的TCP延迟
体验一下:https://http2.akamai.com/demo
参考:https://segmentfault.com/a/1190000016656529?utm_source=tag-newest

增加的特点:

  1. 二进制传输
  2. 多路复用
  3. Header压缩
  4. 服务器Push
  5. 更安全的SSL

5.OkHttp源码看过吗

okhttp是对socket的封装

主要的一些类:OkhttpClient,Request,Response,Call,Dispatcher

  1. new OkHttpClient()创建client对象
  2. 通过Builder设置参数
  3. new Request().Builder().url().builder()创建request对象
  4. 通过client.newCall()创建call对象,使用call.excute()进行同步请求,call.enqueue()进行异步请求
线程池和请求队列

这里call是一个接口,具体实现在reallCall类中
Dispatcher类维护okhttp的线程池和队列:

readyAsyncCalls:待访问请求队列,里面存储准备执行的请求。
runningAsyncCalls:异步请求队列,里面存储正在执行,包含已经取消但是还没有结束的请求。
runningSyncCalls:同步请求队列,正在执行的请求,包含已经取消但是还没有结束的请求。
ExecutorService:线程池,最小0,最大Max的线程池

executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS,
SynchronousQueue(), threadFactory("$okHttpName Dispatcher", false))

虽然线程池设置为MAX,但在调度器中还有其他设置:

@get:Synchronized var maxRequests = 64
@get:Synchronized var maxRequestsPerHost = 5

意思是最大并发数为64,最多开启64线程。
单个Host最多5个请求。

excute和enqueue
  • 同步任务:
    调用ReallCall.excute()方法,此方法里面会调用client.dispatcher.executed(this)进入Dispatcher类,并向runningSyncCalls添加这个请求
  • 异步任务:
    调用ReallCall.enqueue()方法,此方法调用client.dispatcher.enqueue(AsyncCall(responseCallback)),向readyAsyncCalls中添加这个请求。

注意这里this是实现了call接口的对象
AsyncCall()是实现了Runable接口的内联函数,参数responseCallback是CallBack接口,CallBack接口中有两个函数是onFailure,onResponse,这两个函数中的参数还是实现了call接口的对象

ConnectionPool连接池

连接池用来管理socket连接,设置每个地址的连接数最大为5,最长为5分钟。

Okhttp中的设计模式:

单例模式:最好用单例模式创建OkHttpClient,因为每个client对象斗管理自己的线程池、队列,如果每个请求都要创建client对象,那内存就要爆掉了

Builder模式:网络配置需要的属性太多,所以使用了建造者模式(将多个简单的对象构建成一个最终对象 )

策略模式:CacheInterceptor实现了数据的选择策略。CacheInterceptor根据这个策略提供者去选择走网络数据还是本地缓存。

6.TCP-三次握手四次挥手

讲道理这个我也不太清楚,通俗的说法

三次握手:
1)Client:嘿,李四,是我,听到了吗?
2)Server:我听到了,你能听到我的吗?
3)Client:好的,我们互相都能听到对方的话,我们的通信可以开始了。

四次挥手:
1)Client:我所有东西都说完了
2)Server:我已经全部听到了,但是等等我,我还没说完
3)Server:好了,我已经说完了
4)Client:好的,那我们的通信结束

7.Glide原理

//Glide使用方式如下:
Glide.with(context)
.load(path)
.into(iv);
1.Glide的缓存

一种是内存缓存:LruCache,一种是磁盘缓存:DiskLruCache

2.Glide三级缓存

LruCache缓存->弱引用缓存->磁盘缓存

读取一张图片时,先从LruCache缓存读取,找到了就放入WeakReference中,如果没有就去WeakReference中找,还没有就去DiskLruCache、网络请求。

3.Glide加载一个很大的图片到100*100尺寸上,会先压缩再加载吗,放到一个300 * 300的view上会怎样,800 * 800呢,图片会很模糊,怎么处理?

gilde的缓存是根据imageview大小,所以imageview大小改变就会从网络重新加载数据,并以此大小重新缓存。

4.Glide加载的过程中,activity突然关闭会造成内存泄漏吗?

不会!Glide在加载资源的时候,如果在activity、fragment上进行的话,会创建一个透明的requestMangerFragment加入到FragmentManger中,感知生命周期,当activity不可见或者销毁时,Glide会停止加载资源。

5.如何设计一个网络图片加载框架

解析-下载-解码-变换-缓存-显示等操作。

具体一点就是:

  1. 异步加载:线程池
  2. 线程切换:handler
  3. 缓存:Lrucache
  4. 防止OOM:bitmap压缩,合理存储
  5. 内存泄漏:注意imageview持有
  6. 事件处理:点击事件,滑动
6.总结下Glide的优点
  1. 链式加载,使用简单
  2. 多种图片格式
  3. 基于生命周期处理
  4. 高效的缓存策略

参考:https://juejin.im/post/6844903986412126216
https://juejin.im/post/6844904002551808013