使用 RxJava 运算符在 Android 中实现缓存
Android 手机上的缓存是您的应用程序和 Web 浏览器用来提高效率的一小部分信息的集合。 RxOperator 本质上是一个指定 observable 的函数,以及它应该如何以及何时发出数据流。在 RxJava 中,有数百种运算符可供选择。大多数运算符作用于一个 Observable 并返回另一个 Observable。这使您可以一个接一个地在链中应用这些运算符。链中的每个运算符都会更改作为前一个操作员活动结果的 Observable。
首先,我们必须理解为什么缓存是有益的。缓存在以下场景中非常有用:
- 降低数据使用:通过缓存网络响应,我们可以减少网络调用。
- Fast and Rapid:尽可能快地获取数据
极客想知道数据源
假设您有一些想要从网络获取的数据。每次我需要数据时,您都可以连接到网络,但将其存储在磁盘和内存中会更有效率。
合乎逻辑的下一步是在源到达时保存它们。如果您不将网络查询的结果存储到磁盘或在内存中缓存磁盘请求,您将永远不会注意到任何节省!
缓存类型
它可以分为两类
- 内存缓存
- 磁盘缓存
内存缓存:它将数据存储在应用程序的内存中。如果应用程序终止,数据将被弹出。仅适用于同一应用程序会话。因为数据在内存中,所以内存缓存是访问它的最快的缓存。
磁盘缓存:此函数将数据存储到磁盘。即使程序终止,数据也会保留。即使应用程序重新启动后,它仍然有用。因为这是一个 I/O 操作,所以它比内存缓存慢。
当用户第一次启动程序时,内存中没有数据,磁盘缓存中也没有数据。因此,应用程序将需要进行网络调用来检索数据。它将从网络中检索数据,将其存储到磁盘中,将其保留在内存缓存中,然后返回数据。
如果用户在同一个会话期间返回到同一个屏幕,数据会相对较快地从内存缓存中检索出来。如果用户退出并重新启动程序,它会从磁盘缓存中获取数据,保存在内存缓存中,并返回数据。因为每一个数据都是有效的,所以缓存只会在检索时才返回有效的数据。
我们现在了解缓存是如何工作的,在此之前,DataSource 将管理三个数据源,如下所示:
- 记忆
- 磁盘
- 网络
示例 1:数据模型
class GFG {
//Declaring a string
public String gfg;
}
示例 2:内存数据源
// Main class
// gfgDataSource
class GFG {
// Member variables of this class
private Data gfgData;
// Method 1
public Observable getData() {
// Making an observable
return Observable.create(emitter -> {
if (gfgData != null) {
// Emitting the data
emitter.onNext(gfgData);
}
emitter.onComplete();
});
}
// Method 2
void cacheInMemory(Data gfgData) {
// This keyword refers to current object itself
this.gfgData = gfgData.clone();
// Cloning the data for cache
this.gfgData.source = "Spandan Saxena";
}
}
示例 3:磁盘数据源
// Main class
// gfgDiskData
class GFG {
// Member variables of this class
private Data gfgData;
// Method 1
public Observable getData() {
return Observable.create(shooter -> {
if (gfgData != null) {
// Shooting the data to the disk source for usage.
shooter.onNext(gfgData);
}
shooter.onComplete();
});
}
// Method 2
// Main driver method
public void saveToDisk(Data gfgData) {
// Saving the shooted data
this.gfgData = gfgData.clone();
this.gfgData.source = "Spandan Saxena";
}
}
执行:
例子
// Main class
// gfgDataSpace
class GFG {
// Member variables of this class
// A memory data source
private final MemoryDataSource gfgmemoryData;
// A disk data source
private final DiskDataSource gfgDiskData;
// A network data source
private final NetworkDataSource gfgNetwork;
// All these are used as needed.
// Method 1
public DataSource(MemoryDataSource gfgmemoryData,
DiskDataSource gfgDiskData,
NetworkDataSource gfgNetwork)
{
// Pushing the reference
// This keyword refers to current object itself
this.gfgmemoryData = gfgmemoryData;
this.gfgDiskData = gfgDiskData;
this.gfgNetwork = gfgNetwork;
}
// Method 2
public Observable getDataFromMemory()
{
// Getting the data from Mem
// using the cache
return gfgmemoryData.getData();
}
// Method 3
public Observable getDataFromDisk()
{
// Getting the data from Disk
return gfgDiskData.getData().doOnNext(
data -> gfgmemoryData.cacheInMemory(data));
}
// Method 4
public Observable getDataFromNetwork()
{
// No prior cache available, using network
// slow way.
return gfgNetwork.getData().doOnNext(data -> {
gfgDiskData.saveToDisk(data);
gfgmemoryData.cacheInMemory(data);
});
}
}
在这种情况下,我们使用 Concat运算符来保持 observables 的顺序,首先在内存中检查,然后在磁盘中,最后在网络中。因此,Concat运算符将协助我们保持订单。该运算符确保如果我们从内存中接收数据,它不会允许其他可观察对象(磁盘、网络)做任何事情,并且如果我们从磁盘中获取数据,它不会让网络可观察对象做任何事情。因此,没有重复的工作。这就是 firstElement运算符的用武之地。
Conclusion:
This is everything about the RxJava Operators, hope this article cleared the air of the topic and any dust if confusion. Using the RxJava Operators, we can create caching in Android apps.