paging-coroutine
paging-coroutine copied to clipboard
Android paging library which uses Kotlin Coroutine based on androidx.paging
Paging-Coroutine
A paging library which uses Kotlin Coroutine instead of background executor and callback, based on androidx.paging (Ver: 2.1.0) architucture component.
Usage
Dependencies
The paging-coroutine library is avaible on JitPack. Add the JitPack maven repository to the root build.gradle file.
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add the following dependency to the project build.gradle file.
dependencies {
implementation 'com.github.mirmilad:paging-coroutine:v1.0.0-alpha01'
}
This library also needs these dependencies.
dependencies {
implementation "androidx.lifecycle:lifecycle-livedata:2.2.0-rc02" //or above
implementation "androidx.paging:paging-runtime:2.1.0" //or above
}
How to Use
The paging-coroutine library behaves like the original paging library. But there are few modifications on classes name and abstract methods. When you extend a data source, instead of using callbacks to pass data to library, you have to return it.
The following instructions and samples shows how to use paging-coroutine library.
DataSource Implementation
There are different data source classes exactly like the original library data source classes which named with Coroutine prefix.
All of the suspend methods in data source class run on Default dispatcher. If you need to use another dispatcher, you can use coroutineScope property of data source.
For example, extend your data source class from CoroutinePageKeyedDataSource class and implement the required methods like below:
class MyDataSource(api: ApiInterface)
: CoroutinePageKeyedDataSource<Int, MyModel>()
{
override suspend fun loadInitial(params: LoadInitialParams<Int>)
: InitialResult<Int, MovieModel> {
try {
//sample using of a suspend method
val result = api.suspendGetList(...) //blocks current Coroutine till response comes
return InitialResult.Success(result)
} catch (e: Exception) {
//you should notify user
return InitialResult.Error(e)
}
}
override suspend fun loadBefore(params: LoadParams<Int>)
:CoroutinePageKeyedDataSource.LoadResult<Int, MyModel> {
//No Data
return InitialResult.None
}
override suspend fun loadAfter(params: LoadParams<Int>)
: CoroutinePageKeyedDataSource.LoadResult<Int, MyModel> {
//sample of using none suspend method in IO dispatcher
lateinit var retVal: LoadResult<Int, MyModel>;
this.coroutineScope.launch(Dispatchers.IO) {
try {
val result = api.getList(...).execute()
retVal = LoadResult.Success(result)
} catch (e: Exception) {
//you should notify user
retVal = LoadResult.Error(e)
}
}.join()
return retVal
}
}
DataSource.Factory Implementation
Extend your data source factory class from CoroutineDataSource.Factory class and implement create method to return a data source.
class MyDataSourceFactory(private val api: ApiInterface)
: CoroutineDataSource.Factory<Int, MyModel>() {
val sourceLiveData = MutableLiveData<MyDataSource>()
override fun create(): DataSource<Int, MyModel> {
val source = MyDataSource(api)
sourceLiveData.postValue(source)
return source
}
}
LiveData
In order to configure and creating a LiveData, you have to call CoroutineDataSource.Factory.toCoroutineLiveData method. The following code snippet shows how to use this method.
val dataSourceFactory = MyDataSourceFactory(api)
val liveData = dataSourceFactory.toCoroutineLiveData(pageSize = 10)
Lifecycle handling
When you don't need resources and data any more you should release them. By calling CoroutineDataSource.cancelCouroutines() method, all runing coroutines related to this data source will cancel immediately.
If you are using ViewModel you have to call this method inside of onCleared. The following code snippet is an example that shows how to use this method.
class MyViewModel() : ViewModel() {
private val dataSourceFactory = MyDataSourceFactory(api)
val liveData = dataSourceFactory.toCoroutineLiveData(pageSize = 10)
override fun onCleared() {
super.onCleared()
dataSourceFactory.sourceLiveData?.value?.cancelCoroutines()
}
}
Sample Project
For more samples, see the modified version of PagingWithNetworkSample project here. This Sample app was forked from official architecture-components-samples repository and has been modified to use paging-coroutine library.
Compatibility
Since DataSource and PagedList classes are used from origianl library, paging-coroutine library is compatible with PagedListAdapter.
Since PagedList class needs an executor as notifyExecutor, paging-coroutine library still uses MainThreadExecutor.
To Do List
- Writing more tests and coverages
- Removing MainThreadExecutor