How it works ?

Here you can find a detailed explanation of how Livebox works and how you can customize it.

Let's go through a working example to better understand how it works.

// Create validators
Validator<UsersRes> persistentDiskValidator = (key, item) -> Objects.nonNull(item) && !item.getItems().isEmpty();
// Builds an instance of Livebox using LiveboxBuilder class.
Livebox<UsersRes, Users> usersBox = new LiveboxBuilder<UsersRes, Users>()
.withKey("get_users")
.fetch(api::getUserList, UsersRes.class)
.addSource(Sources.MEMORY_LRU, AgeValidator.minutes(2))
.addSource(Sources.DISK_PERSISTENT, persistentDiskValidator)
.addConverter(UsersRes.class, usersRes -> Optional.of(Users.fromUsersRes(usersRes)))
.retryOnFailure()
.build();
// Using scoped feature, this uses Uber's autodispose
usersBox.scoped(AndroidLifecycleScopeProvider.from(this))
.subscribe(
users -> Log.d(TAG, "Users: " + users),
Throwable::printStackTrace
);

Let's go through this code line by line:

  • Line 2 and 3, create the validators to be used when adding data sources.

  • Line 6, use LiveboxBuilder class to create instances of Livebox you should specify the input type and output type. In this case we are excepting to receive UsersRes from fetcher and return an instance of Users class.

  • Line 7, every Livebox instance should have a unique key, this will be used internally to save and read data from cache among other things.

  • Line 8, adds a Fetcher instance that returns an Observable. If you use Retrofit this is a straight forward process. Also due to Java type erasure you need to pass the Type at the second argument.

  • Line 9, adds a data source in this case a built-in in-memory LRU source along with a validator instance. Livebox ships with a built-in AgeValidator that returns false after a certain amount of time, in this case the data has a 2 minute time to live, after 2 minutes the data in data source is considered outdated and is removed.

Each data source needs a validator, when reading data from data sources the validator is called to check if data is valid.

  • Line 10, adds another data source, you can add as many data sources as wanted. This is a built-in persistent disk data source, that writes the data to a file in disk. This file will live forever until the validator for this data source returns false, at that point the file is deleted.

  • Line 11, add a Converter that converts data loaded from data sources to the desired format. In this case converts instances of UsersRes to Users. You can add multiple converters if necessary.

  • Line 12, enable retry on failure behaviour, by default this uses RetryStrategy.INTERVAL, that retries 3 times with a 1 second interval between each try. Please see Retrying for more details.

  • Line 13, builds Livebox instance.

  • Line 16, scope this request using Ubers AutoDispose library. This returns an observable that's bounded to the provided lifecycle.

You can also call asAndroidObservable() or asLiveData() instead of scoped(). Please check Using LiveData and Auto Lifecycle scoping for more details

Flow diagram