Biblioteca de persistência do Android Room Kotlin Coroutines

Tempo de leitura: 2 minutes

Visão geral

A Room suporta coroutines kotlin da versão 2.1 e superior, o que significa que os métodos Dao podem ser marcados como funções suspensas fora da caixa para garantir que as transações da Room não funcionem no thread principal. Continue lendo para aprender como usá-los e como funcionam nos bastidores.

Pré-requisitos

Para entender como as coroutines Kotlin funcionam com o Room Database, você deve saber o que é a biblioteca Room e como ela funciona.

Agora você tem uma ideia sobre a biblioteca Room, e sobre as coroutines. Existem muitos artigos por aí para aprender sobre as coroutines Kotlin, então não vou passar por isso, mas se você quiser aprender, verifique os links a seguir

https://kotlinlang.org/docs/reference/coroutines/basics.html#your-first-coroutine

https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9

Integração

Integração de banco de dados de salas com AndroidX e Kotlin Coroutines compatível com as versões mais recentes no momento.

dependencies {
  def room_version = "2.2.0-rc01"

  implementation "androidx.room:room-runtime:$room_version"
  kapt "androidx.room:room-compiler:$room_version" 
  implementation "androidx.room:room-ktx:$room_version"

}

Mudanças Dao

Vamos criar uma classe de Objeto de Acesso a Dados sem nenhuma corrotina, dê uma olhada

@Dao
interface ShowBasicInfoDao {

    @Query("SELECT * from `SHOW BASIC DATA`")
    fun getAllShows(): Single<List<SeriesDB>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertShowsArray(arrayShows: ArrayList<SeriesDB>) : Completable

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertShow(series: SeriesDB) : Completable

    @Update
    fun updateShow(series: SeriesDB) : Completable

    @Delete
    fun deleteShow(id : Long) : Completable

    @Query("SELECT * FROM `SHOW BASIC DATA` WHERE seriesID = :show_id")
    fun getSelectedShow(show_id : String): Single<SeriesDB>

    @Query("UPDATE `SHOW BASIC DATA` SET lastused=:time WHERE seriesID = :show_idd")
    fun updateLastUsedTime(time : Long,show_id : String)

}

As funções na interface Dao acima são executadas no encadeamento principal, precisamos usar Rxjava ou qualquer outra técnica de gerenciamento de encadeamento para fazer essas funções funcionarem no encadeamento não-UI.

É aqui que as coroutines entram em cena, como eu disse, podemos usar a chave de suspensão com as funções na interface Dao. Dar uma olhada

@Dao
interface ShowBasicInfoDao {

    @Query("SELECT * from `SHOW BASIC DATA`")
    suspend fun getAllShows(): Single<List<SeriesDB>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertShowsArray(arrayShows: ArrayList<SeriesDB>) : Completable

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertShow(series: SeriesDB) : Completable

    @Update
    suspend fun updateShow(series: SeriesDB) : Completable

    @Delete
    suspend fun deleteShow(id : Long) : Completable

    @Query("SELECT * FROM `SHOW BASIC DATA` WHERE seriesID = :show_id")
    suspend fun getSelectedShow(show_id : String): Single<SeriesDB>

    @Query("UPDATE `SHOW BASIC DATA` SET lastused=:time WHERE seriesID = :show_idd")
    suspend fun updateLastUsedTime(time : Long,show_id : String)

}

Agora, com coroutines, as funções no Dao serão executadas no thread não-UI. Vamos ver como usá-los

suspend fun updateShowInLocalDB() {

        updateNetworkStatus(NetworkStatus.loading(true))
        try {
            repo.updateShow(showDetails)
            updateNetworkStatus(NetworkStatus.loading(false))
        } catch (e: Throwable) {
            e.printStackTrace()
            updateNetworkStatus(NetworkStatus.onError(e))
        }
        
    }

Ao contrário do Rxjava, tudo o que precisamos fazer é mencionar a função como suspender para executar essas funções em um thread de segundo plano e usar um bloco try-catch para capturar exceções. Não precisamos aprender nova codificação para usar coroutines, em vez disso, precisamos usar o que sabemos no lugar certo.

Combinação de operações em Dao

Agora com coroutines, a interface Dao pode ser ainda mais útil do que apenas para funções com anotações, dê uma olhada

Dao
abstract class ShowBasicInfoDao {
    
    @Transaction
    open suspend fun setShowDetails(showDetails: ShowDetails) {
        deleteShow(showDetails)
        insertShow(showDetails)
    }

    @Query("DELETE FROM shows")
    abstract fun deleteShow(showDetails: ShowDetails)

    @Insert
    abstract suspend fun insertShow(showDetails: ShowDetails)
}

Não é incrível 🆒

Se houver sugestões ou melhorias, sinta-se à vontade para comentar