Android

How to convert any callback to Coroutines and use them in Kotlin Android?

Hello everyone,

In this article, we are going to learn something to handle the callback by using Kotlin Coroutines. As we are already familiar with Coroutines in my earlier post here get started Coroutines. Alright, then let’s started to learn about the deal with callback in coroutines. 

In android, we mostly use the UseCase to deal with API calls. Generally use case is very useful and provides a safe mechanism to call. I am not going into the deep here. Whenever we hit the API in the use case implementation, we need a callback to check the status of the APIs is either successful or failed.

Let’s take an example to understand the flow. 

interface ApiUseCase {

    suspend fun hitApi(): Result

    sealed class Result {
        data class Success(val result: String) : Result()
        data class Failed(val message: String, val errorCode: Int) : Result()
    }
}

Here I created an Interface of UseCase and a suspend function which is using the Coroutines feature and I want a Result callback either success or failed. Now we need to implement this interface to use this function.

class ApiUseCaseImp : ApiUseCase {

    override suspend fun hitApi(): ApiUseCase.Result =
        withContext(Dispatchers.IO) {
            suspendCoroutine<ApiUseCase.Result> { coroutines -> 
                RetroFitCall() { response ->
                    when (response.responseCode) {
                        200 -> {
                            coroutines.resume(ApiUseCase.Result.Success(""))
                        }
                        else -> {
                            coroutines.resume(
                                ApiUseCase.Result.Failed(
                                    "error message", response.errorCode
                                )
                            )
                        }
                    }
                }
            }
        }

}

Here we use suspendCoroutine as the return block to deal with resume the result back to us either result success of failed. Now lets check how to check the callback result in Coroutines scope. I am assume every one use the ViewModel to call this api. 

class ApiViewModel(private val useCase: ApiUseCase) : ViewModel() {

    private val _apiLiveData = SingleLiveEvent<Resource<String>>()
    val apiLiveData: SingleLiveEvent<Resource<String>>
        get() = _apiLiveData


    fun callApi() {
        viewModelScope.launch {
            _apiLiveData.value = Resource.loading(null)
            when (val result = useCase.hitApi()) {
                is ApiUseCase.Result.Success -> {
                    _apiLiveData.value = Resource.success("")
                }
                is ApiUseCase.Result.Failed -> {
                    _apiLiveData.value = Resource.error(result.message, null, result.errorCode)
                }
            }
        }
    }

Here we use the coroutines scope with Launch function to call the api and check the status of api. As we know Coroutines also provide the feature to cancel the Job if it is required to cancel the api call in between. In this case we need to stop the thread and free the resource.

class ApiViewModel(private val useCase: ApiUseCase) : ViewModel() {

   private val _apiLiveData = SingleLiveEvent<Resource<String>>() 
   val apiLiveData: SingleLiveEvent<Resource<String>> 
   get() = _apiLiveData

   private var apiJob: Job? = null

    fun callApi() {
        apiJob = viewModelScope.launch {
            _apiLiveData.value = Resource.loading(null)
            when (val result = useCase.hitApi()) {
                is ApiUseCase.Result.Success -&gt; {
                    _apiLiveData.value = Resource.success("")
                }
                is ApiUseCase.Result.Failed -&gt; {
                    _apiLiveData.value = Resource.error(result.message, null, result.errorCode)
                }
            }
        }
    }

fun cancelApiJob() {
    if (apiJob != null && apiJob?.isActive == true) {
         apiJob?.cancel()
    }
}

So, today we learned how to convert any callback to Coroutines and use them. That is all for this. Thanks for reading this article.

0 0 votes
Article Rating

Recent Posts

Hide your production API key or any sensitive data in Android

Hi everyone, In this article, we are going to learn how to hide the production… Read More

2 years ago

How to handle the localisation or multi language support in android with examples?

Hello everyone, Today in this article, we are going to learn about localisation to support… Read More

2 years ago

Request Permission Launcher with Kotlin in Android

In this article, we are learning about the run time permissions for request permission launchers.… Read More

2 years ago

Implement the SMS User Consent API and SMS Retriever API in Android

Hello everyone. In my last tutorial, we learned about the Jetpack Compose introduction and about applying the… Read More

3 years ago

Jetpack Compose Coroutine flow with LiveData/ViewModel in Android

Hello everyone, In this article, we are going to learn about the Jetpack Compose with… Read More

3 years ago

Android Jetpack Compose of layouts, row, column, modifier, ConstraintLayout and Scaffold

Hello everyone, In this article, we are going to learn how to use layouts, rows,… Read More

3 years ago