Skip to content

Kotlin Class to provide resource from SQLite and Network concurrently

Notifications You must be signed in to change notification settings

Loriot-n/NetworkBoundResource

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Network Bound Resource

This abstract class provide an easy interface to fetch resource from both the database and the network. It works well with the Android architecture component. Most of the code is taken from this repo.

This is just a demo to illustrate the usage of this concept.

Usage

This class is intended to be called in a Repository to retrieve data for a ViewModel as described here. I included in the repo other classes to tie everything together:

  • AppExecutors allows the different tasks to run on differents threads
  • ApiResponse are the classes for the differents kind of HTTP response
  • Resource allows to wrap the differents states of the request (Loading, Success, Error)

Example

Let's create a Todo list app to illustrate:

Task

@Entity()
data class Task(
    @PrimaryKey
    val id: String,
    val name: String,
    val status: String,
) {}

TaskDao

@Dao
abstract class TaskDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(vararg tasks: Task)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insertMany(tasks: List<Task>)
    
    @Query("SELECT * FROM Task WHERE status IS :status")
    abstract fun loadTasks(status: String): LiveData<List<Task>>
    
    @Query("SELECT * FROM Task WHERE id == :id")
    abstract fun loadTask(id: String): LiveData<Task>

}

HttpService

interface HttpService {
    @GET("/tasks/todo")
    fun getTodos(): LiveData<ApiResponse<List<Task>>>
}

TaskRepository

@Singleton
class TaskRepository @Inject constructor(
    private val appExecutors: AppExecutors,
    private val taskDao: TaskDao,
    private val httpService: HttpService
) {
    fun loadTodos(): LiveData<Resource<List<Task>>> {
        return object : NetworkBoundResource<List<Task>, List<Task>>(appExecutors) {
            override fun saveCallResult(items: List<Task>) {
                taskDao.insertMany(items)
            }

            override fun shouldFetch(data: List<Task>?) = data == null

            override fun loadFromDb(): LiveData<List<Task>> = taskDao.loadTasks("todo")

            override fun createCall() = httpService.getTodos()
        }
    }
}

Now in your ViewModel:

class TodosViewModel @Inject constructor(
    taskRepository: TaskRepository
) : ViewModel() {
    val todos: LiveDate<Resource<List<Task>>> = taskRepository.loadTodos()
}

You should be able to subscribe to your todos and update your UI when the value change!

About

Kotlin Class to provide resource from SQLite and Network concurrently

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages