Skip to content

Data flows

Nikita Kalugin edited this page Apr 18, 2021 · 4 revisions

In this app I'm using a class called NetworkBoundResource. Its described in Google's guide to app architecture.

The following diagram shows the decision tree for NetworkBoundResource:

NetworkBoundResource diagram

It starts by observing the database for the resource. When the entry is loaded from the database for the first time, NetworkBoundResourcechecks whether the result is good enough to be dispatched or that it should be re-fetched from the network. Note that both of these situations can happen at the same time, given that you probably want to show cached data while updating it from the network.

If the network call completes successfully, it saves the response into the database and re-initializes the stream. If network request fails, the NetworkBoundResource dispatches a failure directly.

Actually in the Google's Guide they show kind of old and messy version of NetworkBoundResource class without modern Kotlin features such as Flows.

Here's how the new and improved solution looks like.

inline fun <ResultType, RequestType> networkBoundResource(
        crossinline query: () -> Flow<ResultType>,
        crossinline fetch: suspend () -> RequestType,
        crossinline saveFetchResult: suspend (RequestType) -> Unit,
        crossinline shouldFetch: (ResultType) -> Boolean = { true }
) = flow {
    val data = query().first()

    val flow = if (shouldFetch(data)) {
        emit(Resource.Loading(data))

        try {
            saveFetchResult(fetch())
            query().map { Resource.Success(it) }
        } catch (throwable: Throwable) {
            query().map { Resource.Error(throwable, it) }
        }
    } else {
        query().map { Resource.Success(it) }
    }

    emitAll(flow)
}

So, this approach allows app to work without Internet access as long as it has some cached data in the Room database. And it's working in combination with Glide library and its internal caching mechanism, so not only the data will appears on the screen but also the cached pictures.

Clone this wiki locally