1

I want to implement my custom PagedList.BoundaryCallback with coroutines, liveData and repository pattern using Paging Library 2, but I couldn't find a good example of integration of these libraries.

Even in Android official samples, they use enqueue and callbacks to perform the API request with paging 2...

I read this Medium post also but it use a coroutines scope inside the boundary callback and I think that is not a good practice.

Is there any way to achieve it? Or should I migrate to Paging 3?

Andy
  • 751
  • 1
  • 12
  • 25
  • 1
    You can use `suspendCancellableCoroutine` or `suspendCoroutine` to convert `enqueue` calls into suspend functions. And you can use `callbackFlow` to convert callbacks that get called repeatedly into Flows that you can collect in coroutines. I don't use Paging so can't write a proper answer. The above should be enough for you to Google some examples of how to do these conversions. Though if you're going through the trouble of migrating to coroutines, I don't see why you wouldn't migrate to the latest paging library as well. – Tenfour04 Aug 30 '21 at 16:03
  • I don't know much about the specific paging library, but it's clearly stated on the version 3 that they added first class support for Kotlin coroutines, so I would honestly go for upgrading if that's an option for you. If not, then yes you can use the techniques mentioned by @Tenfour04 – Joffrey Aug 30 '21 at 18:13

1 Answers1

0

This solution works for me:

  1. I injected a CoroutinesDispatcherProvider in my Repository:

    class MyRepository @Inject constructor(
        private val remoteDataSource: MyRemoteDataSource,
        private val localDataSource: MyDao,
        private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider
     ) {...}
    
  2. Then inside my repository, I passed this provider to my boundary callback:

    private val boundaryCallback =
        MyBoundaryCallback(remoteDataSource, localDataSource, coroutinesDispatcherProvider)
    
    fun getList(): LiveData<PagedList<MyModel>> = LivePagedListBuilder(
        localDataSource.getAll(),
        pagedListConfig
    ).setBoundaryCallback(boundaryCallback).build()
    
  3. And finally, I use this dispatcher in my boundary implementation to launch my request from repository:

    private val ioCoroutineScope by lazy {
       CoroutineScope(coroutinesDispatcherProvider.io)
    }
    
    override fun onZeroItemsLoaded() {
        ioCoroutineScope.launch {
            remoteDataSource.getList()
        }
    }
    
Andy
  • 751
  • 1
  • 12
  • 25