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-Callinterface implementation.NetworkResponseAdapter-CallAdapterinterface implementation.NetworkResponseAdapterFactory-CallAdapter.Factoryabstract 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"