java 网络库_网络库浅析

网络方案说明

Android时下最流行的网络方案——“RxJava+Retrofit+OKHttp”,我们先通过官方介绍简单了解一下这几个久仰的大名。

RxJava

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

对于JVM的响应式扩展 ,一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。

Retrofit

Type-safe HTTP client for Android and Java by Square, Inc.

针对于Java和Android的类型安全的Http客户端。

OKHttp

An HTTP+HTTP/2 client for Android and Java applications.

为Android和Java提供的一个兼容Http、Http2协议的客户端。

通过上面的介绍,我们可以得出一个结论。“RxJava+Retrofit+OKHttp”方案,是一个响应式的、类型安全的、兼容Http和Http2的网络方案。这也是我们为什么采用这个方案的原因。想要深刻的理解这个原因,我们需要自行去理解以下几个问题。

什么是响应式变成?

什么是类型安全?

Http协议的相关知识。

问题还有很多,有待大家慢慢发现。

我们的网络库,在上面一些技术的基础上,加入了基于DiskLruCache的数据缓存方案,所以准确的说,我们的网络方案是“RxJava+Retrofit+OKHttp+DiskLruCache”。

其中响应式编程个非常重要的技术概念,甚至可以说是一种编程思想。所以我们会花费一些时间来说一说。

响应式编程

响应式编程是一种通过异步和数据流来构建事物关系的编程模型。

这是一个非常高度概括的、抽象的、脱离了编程的概念描述,这是一个非常准确概念描述,但是说了和没说一样,完全不知道是什么东西。下面我们看一段代码,帮助我们从最根本的出发点上了解这一模型。

int a = 1;

int b = a + 1;

System.out.println(“b = ”+ b) ; // b=2

a = 10;

System.out.println(“b = ”+ b) ;

这一段代码的运行输出是两个b=2,至于为什么,我们在此不做过多的阐述。这段代码的本意其实是b=a+1,也就是说,不论我们将a的值变成多少,b的值都应该是a+1,也就是说第二次打印的预期结果应该是11。

那么我们马上就想到了以下两个办法。

int a = 1;

int b = a + 1;

System.out.println(“b = ”+ b); // b=2

a = 10;

System.out.println(“b = ”+ (a + 1)) ;

int a = 1;

System.out.println(“b = ”+ b); // b=2

a = 10;

int b = a + 1;

System.out.println(“b = ”+ b) ;

上面两段代码,都达到了我们的目的,那么是不是说这两段代码都是响应式编程呢,其实都不是。我们预期的结果,其实是想维持变量a和变量b的一种关系,b=a+1。那么维持这样一个简单的关系为什么就是一种响应式编程呢,这是因为,在一个稳定的关系下,如果一方发生变化,另一方也会随之而发生改变,就好像是b对a的数值变化产生了响应,这就是所谓的响应式编程。

private int a;

private int b;

public void setA(int a) {

this.a = a;

}

public int getB() {

b = a + 1;

return b;

}

以上的这个例子,可以看做是最简单的响应式编程,调用者在每次通过getB()方法获取数据时,都会参照a当前的值进行计算,也就可以看做是对a的数据变化产生了响应。这是一种b对a的主动响应,a并没有对b进行通知。还有一种方式,就是通过观察者模式a的数值发生改变时,主动通知b。

public class Test {

private int a;

private int b;

private OnAChanged onAChanged;

public void setA(int a) {

this.a = a;

onAChanged.onAChanged(a);

}

public int getB() {

return b;

}

public interface OnAChanged {

public void onAChanged(int a);

}

public void setOnAChanged(OnAChanged onAChanged) {

this.onAChanged = onAChanged;

}

public static void main(String[] args) {

Test test = new Test();

test.setOnAChanged(new OnAChanged() {

@Override

public void onAChanged(int a) {

test.setB(a + 1);

}

});

}

}

经过更加复杂和完善的设计,并且完美的解决的多线程异步、代码耦合等问题,RxJava也就应运而生了。

Ps:响应式编程的思想广泛出现在我们的生活和编码中,但是这种响应本质上是对信息的响应,无非是a发生改变时主动通知b,或者b在需要的时候通过观察a得到信息。其实,理想状态下的响应是不依赖于消息的,a发生改变后,b马上发生改变,不需要任何的信息传递。这种玄而又玄的理想的响应式编程模型,只出现在神奇的量子力学领域,这种现象叫做量子纠缠。

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

量子纠缠.png

RxJava-Retrofit-OkHttp的关系

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

RxJava-Retrofit-OkHttp.png

上图描述的是三个库之间的依赖关系,其中OkHttp是基础,Retrofit是桥梁,RxJava表现形式,其中Retrofit对OkHttp具有极强的依赖性。

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

网络关系图.png

上图是一个网络的职能和相互关系的简单示意图,它们的职能分别如下。

OKHttp,负责与网络交互,为Retrofit提供发起网络请求和获得响应数据的方法。

Retrofit,负责对接口、参数进行封装,发起网络请求,得到网络数据并以Flowable等形式传递给RxJava。

RxJava以Consumer、Subscriber等形式接收Retrofit封装后的Flowable类型的网络数据,并回调到业务层处理。

network网络库

做了这么多的铺垫,下面才要进入正题了,我们看一下网络框架的依赖关系。

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

network_uml.png

从图上看,整个网络库在关系上并没有非常复杂的相互依赖关系,我们只需要以NetHelper为出发点,就可以理清整个库的逻辑了。

NetHelper有以下一些能力。

createClient()

创建可以添加通用参数、通用Header、自定义拦截器,具备网络缓存功能和支持Https的OKHttpClient对象。

createRetrofit()

可以根据URL的不同,可以创建多个Retrofit对象。

request()

发起网络请求。

requestLocalFirst()

先读取本地缓存数据再发起网络请求。

addCommonParams()

在网络库初始化之后加入通用参数。

NetOptions

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

NetOptions.png

网络基础配置项,使用builder模式,配置项包括:

支持使用者添加的

interceptors - 网络拦截器,用于添加自定义拦截器

commonParams - 通用参数,通用参数可以通过添加自定义拦截器添加,也可以将通用参数的键值对加入commonParams

commonHeaders - 通用请求头,通用请求头可以通过添加自定义拦截器添加,也可以将通用headers的键值对加入commonHeaders

超时相关

connectTimeout - 链接超时时长,默认10秒

readTimeout - 读取操作超时时长,默认60秒

writeTimeout - 写操作超时时长,默认60秒

timeUnit - 超时时长的时间单位,默认是秒,@see {@link TimeUnit},会影响上面三个超时时长

缓存相关

cacheSize - 网络缓存文件大小,默认是10M

cacheDir - 网络缓存文件的路径,默认是context.getCacheDir()+/xes/network;

cache

使用DiskLruCache是因为OKHttp自带的网络缓存只支持GET请求,POST请求无法进行数据缓存。为了对数据缓存进行统一的管理,使用DiskLruCache对网络数据进行磁盘缓存。

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

cache.png

介绍几个比较重要的方法

String createCacheKey(Request request)

根据拦截器中的Request对象生成数据缓存的key,其实就是网络请求的URL,不带参数。

String createCacheValue(Response response)

根据拦截器中的Response对象生成数据缓存的value,格式是time(long)#responseContent。

savePostRespones(Request request, Response response)

根据Request和Response对接口数据进行磁盘缓存。

converter

自定义XesConverterFactory代替Retrofit的GsonConverterFactory,达到同事支持String和JsonBean的目的。

https

网络框架支持https请求,目前采用信任所有证书的方案,不进行证书校验。

retrofit_url

历史遗留内容,不作为对外开放的功能,主要作用是通过识别header中的DOMAIN_NAME对url进行动态切换。

interceptor

这是一个比较重要的内容,包含以下一些方面。

HeadersInterceptor

通过持有NetOptions的commonHeaders属性,拦截请求添加通用header。

ParamsInterceptor

通过持有NetOptions的commonParams属性,拦截请求添加通用参数。

LocalCacheInterceptor

无网络时,识别缓存设置,直接拦截请求返回本地缓存数据。

NetCacheInterceptor

接口访问成功时,识别缓存设置,保存接口数据。

3e92bcb9c564?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

拦截器工作图.png

后期需要完善的地方

网络缓存目前只支持按照url进行缓存,如果一个接口在多处调用,缓存数据无法区分。

先读取本地后请求网络的API需要传入5个参数,使用不方便。

网络缓存只能保证缓存请求成功的数据,status!=0的错误数据也会缓存。

SSL证书识别认证。

运行过程中修改通用参数、通用header等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值