Sample Android application that show how can we create our own Retrofit CallAdapter
for Coroutines to handle response as states.
By creating your own CallAdapter
, you can do the following:
interface Service {
@GET("movies/{id}")
suspend fun getMovie(): NetworkResponse<Movie, MovieError>
}
class Repository {
val movie = service.getMovie()
when (movie) {
is NetworkResponse.Success -> // Success response
is NetworkResponse.ApiError -> // Failure response (non-2xx)
is NetworkResponse.NetworkError -> // Network failure
is NetworkResponse.UnknownError -> // Unexpected exceptions
}
}
The implementation of CallAdapter
in the application is defined through the following classes:
NetworkResponse
- Sealed class that represents the API call response states.NetworkResponseCall
-Call
interface implementation.NetworkResponseAdapter
-CallAdapter
interface implementation.NetworkResponseAdapterFactory
-CallAdapter.Factory
abstract class implementation.
Also you need to make Retrofit aware of our custom CallAdapter.Factory
:
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addCallAdapterFactory(NetworkResponseAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
This sample application uses Architecture Components to separate the UI code in MainActivity
from the application logic in MainViewModel
. MovieRepository
(and its concrete MovieRepositoryImpl
implementation) provides a bridge between the ViewModel
and MovieService
, which uses Retrofit to return a list of Movie
objects.
To use this sample application you need to register your own TMDb API key and add it to the file NetworkModule.kt
:
const val API_KEY = "INSERT-API-KEY-HERE"