Kotlin Coroutines the right way in Android

前端 未结 9 1119
醉酒成梦
醉酒成梦 2020-12-02 06:51

I\'m trying to update a list inside the adapter using async, I can see there is too much boilerplate.

Is it the right way to use Kotlin Coroutines?

can this

9条回答
  •  不知归路
    2020-12-02 06:58

    Please find attached the implementation for a remote API call with Kotlin Coroutines & Retrofit library.

    import android.view.View
    import android.util.Log
    import androidx.lifecycle.MutableLiveData
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.viewModelScope
    import com.test.nyt_most_viewed.NYTApp
    import com.test.nyt_most_viewed.data.local.PreferenceHelper
    import com.test.nyt_most_viewed.data.model.NytAPI
    import com.test.nyt_most_viewed.data.model.response.reviews.ResultsItem
    import kotlinx.coroutines.*
    import javax.inject.Inject
    
    class MoviesReviewViewModel @Inject constructor(
    private val nytAPI: NytAPI,
    private val nytApp: NYTApp,
    appPreference: PreferenceHelper
    ) : ViewModel() {
    
    val moviesReviewsResponse: MutableLiveData> = MutableLiveData()
    
    val message: MutableLiveData = MutableLiveData()
    val loaderProgressVisibility: MutableLiveData = MutableLiveData()
    
    val coroutineJobs = mutableListOf()
    
    override fun onCleared() {
        super.onCleared()
        coroutineJobs.forEach {
            it.cancel()
        }
    }
    
    // You will call this method from your activity/Fragment
    fun getMoviesReviewWithCoroutine() {
    
        viewModelScope.launch(Dispatchers.Main + handler) {
    
            // Update your UI
            showLoadingUI()
    
            val deferredResult = async(Dispatchers.IO) {
                return@async nytAPI.getMoviesReviewWithCoroutine("full-time")
            }
    
            val moviesReviewsResponse = deferredResult.await()
            this@MoviesReviewViewModel.moviesReviewsResponse.value = moviesReviewsResponse.results
    
            // Update your UI
            resetLoadingUI()
    
        }
    }
    
    val handler = CoroutineExceptionHandler { _, exception ->
        onMoviesReviewFailure(exception)
    }
    
    /*Handle failure case*/
    private fun onMoviesReviewFailure(throwable: Throwable) {
        resetLoadingUI()
        Log.d("MOVIES-REVIEWS-ERROR", throwable.toString())
    }
    
    private fun showLoadingUI() {
        setLoaderVisibility(View.VISIBLE)
        setMessage(STATES.INITIALIZED)
    }
    
    private fun resetLoadingUI() {
        setMessage(STATES.DONE)
        setLoaderVisibility(View.GONE)
    }
    
    private fun setMessage(states: STATES) {
        message.value = states.name
    }
    
    private fun setLoaderVisibility(visibility: Int) {
        loaderProgressVisibility.value = visibility
    }
    
    enum class STATES {
    
        INITIALIZED,
        DONE
    }
    }
    

提交回复
热议问题