Open In App

Implement Caching in Android Using RxJava Operators

Last Updated : 30 Sep, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

The cache on your Android phone is a collection of little pieces of information that your apps and web browser utilize to improve efficiency. RxOperator is essentially a function that specifies the observable, as well as how and when it should emit the data stream. In RxJava, there are hundreds of operators to choose from. The majority of operators act on an Observable and return another Observable. This allows you to apply these operators in a chain, one after the other. Each operator in the chain alters the Observable that is the outcome of the preceding operator’s activity.

First, we must comprehend why caching is beneficial. Caching is extremely beneficial in the following scenarios:

  • Lowering Data Usage: By caching network responses, we may reduce network calls.
  • Fast and Rapid: Fetch the data as quickly as possible

Geek wondered about the  Data Sources

Assume you have some data that you want to get from the network. You could just connect to the network each time I need the data, but storing it on disc and in memory would be far more efficient.

The logical next step is to save sources as they arrive. You’ll never notice any savings if you don’t store the results of network queries to disc or cache disc requests in memory!

Types of caching

It can be classified into two types

  • Memory cache
  • Disk cache

Memory Cache: It stores data in the application’s memory. The data is ejected if the application is terminated. Only applicable within the same application session. Because the data is in memory, the memory cache is the quickest cache to access it.
Disk Cache: This function stores data to the disc. The data is kept even if the program is terminated. Even after the application has restarted, it is still useful. Because this is an I/O operation, it is slower than memory cache.

Image #1. Understanding Caching in Android.

When the user launches the program for the first time, there will be no data in memory and no data in the disc cache. As a result, the application will need to make a network call to retrieve the data. It will retrieve data from the network, store it to disc, retain it in-memory cache, and then return the data.

If the user returns to the same screen during the same session, the data will be retrieved from the memory cache relatively quickly. If the user exits and restarts the program, it will get the data from the disc cache, save it in the memory cache, and return the data. Because every data has validity, the cache will only return the data if it is valid at the moment of retrieval.

We now understand how caching works, prior to it the DataSource will manage three data sources as follows:

  1. Memory
  2. Disk
  3. Network

Example 1: A Data Model

class GFG {
    
    //Declaring a string
    public String gfg;
}

Example 2: Memory data source 

// Main class
// gfgDataSource
class GFG {

  // Member variables of this class
  private Data gfgData;

  // Method 1
  public Observable<Data> 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";
  }
}

Example 3: A Disk Data Source

// Main class
// gfgDiskData
class GFG {

  // Member variables of this class
  private Data gfgData;

  // Method 1
  public Observable<Data> 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";
  }
}

Implementation:

Example

// 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<Data> getDataFromMemory()
    {

        // Getting the data from Mem
        // using the cache
        return gfgmemoryData.getData();
    }

    // Method 3
    public Observable<Data> getDataFromDisk()
    {

        // Getting the data from Disk
        return gfgDiskData.getData().doOnNext(
            data -> gfgmemoryData.cacheInMemory(data));
    }

    // Method 4
    public Observable<Data> getDataFromNetwork()
    {

        // No prior cache available, using network
        // slow way.
        return gfgNetwork.getData().doOnNext(data -> {
            gfgDiskData.saveToDisk(data);
            gfgmemoryData.cacheInMemory(data);
        });
    }
}

In this case, we utilized the Concat operator to keep the order of the observables, which is first checked on memory, then in the disc, and finally in the network. As a result, the Concat operator will assist us in keeping the order. This operator ensures that if we receive the data from memory, it does not allow the other observables (disc, network) to do anything and that if we get the data from the disc, it does not let the network observable do anything. As a result, there is no duplicate work. This is where the firstElement operator comes in.

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.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads