0
点赞
收藏
分享

微信扫一扫

RxHttp 全网Http缓存最优解,缓存架构技术

彭维盛 2022-02-04 阅读 86

以上代码,为单个请求设置了单独的缓存策略,其中有效时长为10秒,缓存模式为先读取缓存,失败后,再请求网络。如果不设置,将使用全局的缓存策略。

注:设置单独的缓存模式/缓存有效时长前,一定要设置缓存存储目录和缓存最大Size,否则无效

4、关于CacheKey

CacheKey在RxHttp的缓存模块中,是一个很重要的角色,内部缓存的读写、删除都是通过CacheKey来操作的。对于不相同的请求,要保证CacheKey的唯一性;对于相同的请求,要保证CacheKey的静态性,这两个特性非常重要,一定要保证,否则缓存将变得毫无意义。

为啥这么说,请往下看。

4.1、内部CacheKey的生成规则

RxHttp内部会根据一定规则,为每个请求,都生成一个具有唯一性的CacheKey,规则如下:

NoBodyParam

将添加的参数拼接在url后面,如:CacheKey = url?key=value&key1=value1… ,Get、Head类型请求遵循这个规则

FormParam

同NoBodyParam,将添加的参数拼接在url后面,如:CacheKey = url?key=value&key1=value1… , xxxForm类型请求遵循这个规则

JsonParam

将添加的参数转换成Json字符串jsonStr后,添加到url后面,如:CacheKey = url?json=jsonStr , xxxJson类型请求遵循这个规则

JsonArrayParam

同JsonParam,将添加的参数转换成Json字符串jsonStr后,添加到url后面,如:CacheKey = url?json=jsonStr, xxxJsonArray类型请求遵循这个规则

以上4个规则,可在对应的Param类中getCacheKey()方法查看

4.2、自定义CacheKey

如果以上规则不能满足你的业务需求,RxHttp还提供了两种自定义CacheKey的方式,如下:

1、通过RxHttp#setCacheKey(String)方法,为单个请求指定CacheKey

RxHttp.get("/service/…")
.setCacheKey(“自定义的CacheKey”) //自定义CacheKey
.asString()
.subscribe(s -> {
//成功回调
}, throwable -> {
//失败回调
});

2、通过自定义Param,并重写getCacheKey()方法,为某一类请求制定CacheKey的生成规则,如下:

@Param(methodName = “postEncryptForm”)
public class PostEncryptFormParam extends FormParam {

public PostEncryptFormParam(String url) {
super(url, Method.POST);
}

@Override
public String getCacheKey() {
String cacheKey = null;
String simpleUrl = getSimpleUrl(); //拿到Url
Headers headers = getHeaders();//拿到添加的请求头
List keyValuePairs = getKeyValuePairs(); //拿到添加的参数
cacheKey = “根据url/请求头/参数,自定义规则,生成CacheKey”;
return cacheKey;
}
}

注:自定义CacheKey,一定要保证CacheKey的唯一性,若重复,将覆盖已存在的缓存

4.3、唯一性

唯一性,就是要保证不同的请求都具有不同的CacheKey。若相同,就会造成缓存错乱

举个例子:

有A、B两个不同的请求,CacheKey、缓存模式均一样,缓存模式为READ_CACHE_FAILED_REQUEST_NETWORK,即先读缓存,失败后,再请求网络。

此时,A先发请求,步骤为:读缓存失败—>请求网络—>请求成功,写入缓存—>结束;

随后B发起请求,步骤为:读缓存成功—>结束;

因为A和B的CacheKey是一样的,所以B读缓存时,读到的就是A的。而且,如果B的缓存模式为REQUEST_NETWORK_FAILED_READ_CACHE,此时,如果B请求成功,写缓存时,因为CacheKey一样,就会把A的缓存覆盖掉,下次A读取缓存时,读的就是B的缓存,这就是我说的缓存错乱

4.4、静态性

何为静态性?我对它的定义是:同一个请求,发送多次,要保证CacheKey是一致的,否则,缓存将毫无意义。

试想,我们有这样一种情况,每次发送请求,都要带上当前的时间戳,如下:

RxHttp.get("/service/…")
.add(“currentTime”, System.currentTimeMillis())
.setCache(CacheMode.READ_CACHE_FAILED_REQUEST_NETWORK) //当前请求先读取缓存,失败后,再请求网络
.asString()
.subscribe(s -> {
//成功回调
}, throwable -> {
//失败回调
});

上面的代码,每次发起请求,时间戳都不一样,就导致内部每次生成的CacheKey也不一样,从而造成每次都会写入相同的缓存而不覆盖,更严重的是,每次读取缓存都会失败,那我们如何避免这种情况呢?有,前面介绍的,自定义Cachekey就能解决这个问题,那还有没有更简单的办法呢?也有,往下看。

剔除不参与CacheKey组拼的参数

我们可以调用RxHttpPlugins.setExcludeCacheKeys(String... keys)方法,设置不参与CacheKey组拼的参数,即剔除这些参数。对于上面的问题,就可以这么做:

RxHttpPlugins.setExcludeCacheKeys(“currentTime”) //可变参数,可传入多个key

此时,发送请求,当前时间戳就不会参与CacheKey的组拼,从而保证了每次发起请求,CacheKey都是一样的,这就是我说的静态性

5、扩展

到这,也许有人会问我,我有这么一种业务场景:打开app,列表先展示缓存的数据,随后再请求网络,拉取最新的数据,用RxHttp如何实现?

对于这种场景,我们需要这样一种缓存模式,即:先读取缓存,不管成功与否,都继续请求网络。然而,RxHttp的5中缓存模式中,没有这样一种模式,怎么办?既然提出来了,肯定有办法,通过两种模式的组合来实现这个场景,如下:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//发送一个仅读取缓存的请求
requestData(CacheMode.ONLY_CACHE);
//接着在发送一个请求网络,成功后写缓存的请求

最后

简历首选内推方式,速度快,效率高啊!然后可以在拉钩,boss,脉脉,大街上看看。简历上写道熟悉什么技术就一定要去熟悉它,不然被问到不会很尴尬!做过什么项目,即使项目体量不大,但也一定要熟悉实现原理!不是你负责的部分,也可以看看同事是怎么实现的,换你来做你会怎么做?做过什么,会什么是广度问题,取决于项目内容。但做过什么,达到怎样一个境界,这是深度问题,和个人学习能力和解决问题的态度有关了。大公司看深度,小公司看广度。大公司面试你会的,小公司面试他们用到的你会不会,也就是岗位匹配度。

选定你想去的几家公司后,先去一些小的公司练练,学习下面试技巧,总结下,也算是熟悉下面试氛围,平时和同事或者产品PK时可以讲得头头是道,思路清晰至极,到了现场真的不一样,怎么描述你所做的一切,这绝对是个学术性问题!

面试过程一定要有礼貌!即使你觉得面试官不尊重你,经常打断你的讲解,或者你觉得他不如你,问的问题缺乏专业水平,你也一定要尊重他,谁叫现在是他选择你,等你拿到offer后就是你选择他了。

金九银十面试季,跳槽季,整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

本文在开源项目:【GitHub 】中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md) 】中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…**

举报

相关推荐

0 条评论