Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

568
Visualizações
In Activity/Fragment, How to get/wait the return value from ViewModel coroutines operation?

Following the codelab demo from Google (link), I try to refactor my code to ViewModel + coroutines. My question is, instead of just insert the data (original code), I want to wait for the result from the inserting operation, which should return the id if the inserting succeeded, then do something based on the result. So how to do it?

Currently, I send a method to the ViewModel insert method as a callback. Of course, observing the ViewModel is another option. But is there any better solution?

My current code:

EventActivity:

viewModel.insert(Event("name"), {
    if (it == -1L) {
        Log.i("insert", "failure")
    } else {
        Log.i("insert", "success: $it")
    }
})

EventViewModel:

private val mEventDao: EventDao = AppDatabase.getDatabase(application).eventDao()
private val mJob = Job()
private val mScope = CoroutineScope(Dispatchers.Main + mJob)

fun insert(event: Event, callback: (id: Long) -> Unit) {
    mScope.launch(Dispatchers.IO) {
        val result =
            try {
                // just for testing delay situation
                delay(5000)
                val id = mEventDao.insertEvent(event)
                id
            } catch (e: Exception) {
                -1L
            }
        withContext(Dispatchers.Main) {
            callback(result)
        }
    }
}

EventDao:

@Dao
interface EventDao {
    fun insertEvent(event: Event): Long
}
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You can add a LiveData object to EventViewModel, update it when inserting is done and subscribe to it in Activity:

class EventViewModel : ViewModel() {
    //...
    var insertionId = MutableLiveData<Long>()

    fun insert(event: String) {
        mScope.launch(Dispatchers.IO) {
            val result =
                    try {
                        // just for testing delay situation
                        delay(5000)
                        val id = mEventDao.insertEvent(event)
                        id
                    } catch (e: Exception) {
                        -1L
                    }

            insertionId.postValue(result)
        }
    }
}

And subscribe in the EventActivity:

class EventActivity : AppCompatActivity() {

    lateinit var viewModel: EventViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel = ViewModelProviders.of(this).get(EventViewModel::class.java)
        viewModel.insertionId.observe(this, android.arch.lifecycle.Observer { id ->
            // Use `id` for example to update UI. 
        })

        // ...

        viewModel.insert(Event("name"))
    }
}
over 4 years ago · Santiago Trujillo Relatório

0

  suspend fun insert(data: String): String = suspendCoroutine { cont ->
    //put logic here
    cont.resume("Done")

    //if error use this
    cont.resumeWithException(Exception("Error"))
  }

i can remove callback in this function with return and wait the return

  fun insertData(){
    GlobalScope.launch {
      val status = insert("This is Data!")

      if( status == "Done"){
      }else{
      }
    }
  }
over 4 years ago · Santiago Trujillo Relatório

0

But is there any better solution?

i think there is.

in androidx.lifecycle.*:2.2.0 alpha01 the liveData { . . . } , emit() functions are available.

you can rewrite your code in viewModel like this.

fun insertData(event: String) = liveData {
        val id = mEventDao.insertEvent(event)
        emit(id)
    }

and in your activity observe it.

viewModel.insertData("YourEvent").observe(this) {
            updateUi(id)
    }

don't forget to change your Dao methods to suspend

@Dao
interface EventDao {
    suspend fun insertEvent(event: Event): Long
}

BTW at this time the latest version of live data is 2.2.0-rc03

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-rc03"

you can see better implementation in android documentation : Use coroutines with LiveData

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda