Playing with…
Paging Library, Retrofit, Coroutines, Koin & Testing.

Those last days, I really wanted to create an application around the Android Paging Library, especially with Retrofit. Pagination is a feature quite famous in our world, but not so easy to implement.
So I decided to build a showcase app that will fetch developers from Github, with pagination, depending on the user’s search. I also chose to use those libs :
- Kotlin Coroutines: For asynchronous programming.
- Koin: For dependency injection.
You can download the final debug APK directly on Github.
1. How does this app work?

The application is pretty easy to understand. You have a Toolbar with a “Search” icon. When the user clicks on it, he can start typing its search: for each letter hit, the RecyclerView is refreshed and a brand new request on Github’s API is run (if a previous one run, it will be canceled).
A circular progress bar is shown at the bottom of RecyclerView to indicate that another next request (pagination) is loading.
The user can also filter the query via a dialog after having touched the FAB.

I also wanted to handle network errors, because it can happen (obviously), and the user needs to be notified about it. So in this app, there are two types of error:
- Pagination error: when the first query was correctly made, but the second one failed… In this case, we show a message and a button to the user allowing him to retry the failed request.
- Global error: when the first query has failed… In this case, we show a message and a refresh button instead of the RecyclerView.
2. How this app is designed?

This design is relatively straightforward.
First, we have a fragment that contains a RecyclerView bound with the PagedList
through a LiveData
. As you may know, a PagedList is a List
which loads its data in chunks (pages) from a DataSource
which is created by a DataSource.Factory
.
In our example, UserDataSource
will NOT fetch data directly. Instead, it will ask UserRepository
to do it.
3. Show me the code!
You can find the full code of this project at this repository: https://github.com/PhilippeBoisney/GithubApp.
3.1. Retrofit & Coroutines
First of all, when you want to use the coroutines with Retrofit, you simply have to make each call return a Deferred
response.
Then in the UserRepository
, you will have to call each previous one through suspend
functions, thanks to .await()
method :
Those suspend
functions are actually pretty readable (even if you don’t know about the coroutines) and it seems easy to guess what each one is going to fetch on the Github’s API.
If you want to get more information about Retrofit with the coroutines, I highly encourage you to read this article by Joe Birch. This article from Dmytro Danylyk about coroutines is also really helpful.
3.2. Paging Library
Now that our network requests are ready, we will have to configure some classes from the Paging Library. First of all, we will have to create the UserDataSource
:
As you can see, this class is the heart of the paging feature and inherits of PageKeyedDataSource
(FYI, James Shvarts explains perfectly the three types of DataSource you can use).
The most important method above is the executeQuery()
: it will simply launch a new coroutine that will fetch data on Github’s API. I’m also using a SupervisorJob
in order to be able to handle more easily and independently possible failures or cancellations of child jobs.
Also, I’m using a CoroutineExceptionHandler
to properly manage uncaught exceptions.
Finally, the UserDataSource
will be created by its factory, UserDataSourceFactory
which inherits of DataSource.Factory
:
As you may have noticed previously, I passed twice a CoroutineScope
object and a UserRepository
object to the constructors of both UserDataSource
and UserDataSourceFactory
.
Actually, those objects have been originally created by SearchUserViewModel
. In this way, when the VM will be destroyed, it will be easy to cancel possible running coroutines.
3.3. ViewModel
SearchUserViewModel
will basically construct every previous object in order to create a LiveData
of PagedList
:
To give you more context, here is the BaseViewModel
class :
3.4 Koin
What about dependency injection? I chose to use Koin for this project, especially because it’s extremely easy to use and even more to read.
For example, here is the Koin network module for this app :
Still not convinced? Let’s check the ViewModel module :
Impossible to make it more clear 👌
4. What about the test?
4.1 Unit Tests
Koin and the Coroutines make unit tests more comfortable and easy to read :
FYI, I used MockWebServer to mock an HTTP server and its custom responses.
4.2 Instrumented Tests
Again, Koin makes testing more simple, especially when it comes to updating dependencies of a controller (Activity/Fragment) BEFORE each test.
Maybe have you spotted the Thread.sleep(1000)
? Pretty bad isn’t it? I’m not sure why, but the RecyclerView takes some time to disappears when no data is loaded… I will investigate this week to try to find a proper solution to this problem and I will replace this quick fix ASAP.
In this post, we’ve seen how to use Android Paging Library with Retrofit & Coroutines. I hope you can see how testing is easy using Koin & Coroutines. If you have any questions or comments then please feel free to reach out!