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

308
Visualizações
Habitación con Kotlin-coroutines observar cambios de db

Entonces, recientemente comencé a experimentar con corrutinas, cambié de Rxjava2 a corrutinas, aún no lo entiendo, pero aún así, me encontré con una condición en la que necesitaba observar el cambio de mi base de datos y actualizar la interfaz de usuario correspondiente a eso.

RxJava solía proporcionarme Flowables, Completeable, etc. con eso podría observar cambios en Db.

 abstract fun insert(data: SomeData): Long @Query("SELECT * FROM somedata_table") abstract fun getData(): Flowable<List<SomeData>>

Así que aquí ahora solía suscribirme a getData y siempre solía observar los cambios.

Ahora ingrese coroutines, estoy usando una función suspendida con un resultado diferido para devolver mis respuestas

 @Insert(onConflict = OnConflictStrategy.IGNORE) abstract fun insert(data: SomeData): Long @Query("SELECT * FROM somedata_table") abstract fun getData(): List<SomeData>
 suspend fun getAllSomeData():Deferred<List<SomeData>>{ return GlobalScope.async (context= coroutineContext){ database.myDao().getData() } }

Ahora no tengo forma de escuchar las actualizaciones, ¿los canales en las corrutinas podrían ser la respuesta correcta? pero no estoy seguro de cómo usarlo con Room.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Use Room 2.2.0 Flujos y corrutinas kotlin . Es polémico, pero no me gusta LiveData , ya que te da resultados en el subproceso de la interfaz de usuario. Si tiene que hacer algún análisis de datos, tendrá que devolver todo a otro subproceso de IO. También es más limpio que usar los canales directamente, ya que tiene que hacer más llamadas openSubscription().consumeEach { .. } cada vez que quiera escuchar eventos.

Enfoque de flujo Requiere las siguientes versiones:

// esta versión usa rutinas y flujos en su versión no experimental

 org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2 androidx.room:room-runtime:2.2.0 androidx.room:room-compiler:2.2.0

dao:

 @Dao interface MyDao { @Query("SELECT * FROM somedata_table") fun getData(): Flow<List<SomeData>> }

clase para hacer observación:

 launch { dao.getData().collect { data -> //handle data here } }

si su clase de llamada no es en sí misma un CoroutineScope , tendría que llamar al lanzamiento con el contexto de algo que sí lo es. Eso puede ser GlobalScope o alguna otra clase que cree. Aquí estoy usando lifecycleScope asumiendo que estamos en una clase de actividad.

 lifecycleScope.launch { dao.getData().collect { data -> //handle data here } }

el lambda recopilado recibirá cada actualización de la tabla como una llamada Rx onNext .

over 4 years ago · Santiago Trujillo Relatório

0

Actualmente, hay dos formas diferentes de hacerlo. La primera es usar una función de generador de datos en vivo. Para que esto funcione, debe actualizar el ciclo de vida a androidx.lifecycle:*:2.2.0-alpha01 o cualquier versión más reciente. La función del constructor LiveData se usará para llamar a getData() de forma asíncrona y luego usar emit() para emitir el resultado. Usando este método, modificará su función Room getData() a una función de suspensión y hará que el tipo de retorno se envuelva como LiveData, reemplazando el Flowable usado antes.

 @Query("SELECT * FROM somedata_table") abstract suspend fun getData(): LiveData<List<SomeData>>

En su modelo de vista, crea un liveData que hace referencia a su base de datos Room

 val someData: LiveData<SomeData> = liveData { val data = database.myDao().getData() emit(data) }

El segundo enfoque es obtener datos de nuestra base de datos como flujo. Para usar esto, debe actualizar Room a androidx.room:room-*:2.2.0-alpha02 (actualmente la última) o una versión más nueva. Esta actualización permite que los métodos @Query DAO sean del tipo de retorno Flujo El flujo devuelto volverá a emitir un nuevo conjunto de valores si se invalidan las tablas de observación en la consulta. Declarar una función DAO con un tipo de retorno de Canal es un error

 @Query("SELECT * FROM somedata_table") abstract fun getData(): Flow<List<SomeData>?>

El tipo de retorno es un flujo de una lista anulable. La lista se puede anular porque Room devolverá un valor nulo cuando la consulta no tenga datos obtenidos.

Para obtener datos del flujo, utilizaremos el operador de terminal collect{ } en nuestro Presenter/ViewModel. Es preferible hacer esto en ViewModel ya que viene con un ViewModelScope. La solución que se proporciona a continuación supone que estamos haciendo esto en un ViewModel donde tenemos un viewModelScope proporcionado.

 fun loadData(){ viewModelScope.launch { database.myDao() .getData() .distinctUntilChanged(). .collect{ it?.let{ /** Update your obsevable data here **/ } }
over 4 years ago · Santiago Trujillo Relatório

0

Dependencias de Gradle:

 dependencies { compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-reactive', version: '1.1.1' }

Habitación Dao

 @Dao interface HistoryDao : BaseDao<HistoryEntity> { @Query("select * from History order by time desc") fun observe(): Flowable<List<HistoryEntity>> ... }

Interactor ( browserHistoryInteractor debajo) (capa entre dao y Fragment/Presenter)

 // To get channel of List<HistoryEntity>: import kotlinx.coroutines.reactive.openSubscription fun observe() = historyDao.observe().openSubscription() // convert list to Coroutines channel

Presentador/Fragmento/Actividad (punto final (en mi caso, es un presentador consciente del ciclo de vida))

 import kotlinx.coroutines.Job import kotlinx.coroutines.launch private val compositeJob = Job() // somewhat equivalent "compositeDisposable" in rx override fun onCreate() { super.onCreate() launch(compositeJob) { // start coroutine val channel = browserHistoryInteractor.observe() for (items in channel) { // waits for next list of items (suspended) showInView { view?.setItems(items) } } } } override fun onDestroy() { compositeJob.cancel() // as in rx you need to cancel all jobs super.onDestroy() }

https://www.youtube.com/watch?v=lh2Vqt4DpHU&list=PLdb5m83JnoaBqMWF-qqhZY_01SNEhG5Qs&index=5 a las 29:25

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
Assistente virtual