7
respostas

coroutine com lateinit var

Olá

Estou usando a biblioteca Room para armazenamento interno de dados e para otimizar o processamento estou usando as coroutines.

Tenho uma variável que declarei como lateinit.

    private lateinit var alimentos: MutableList<Alimento>

Ela receberá uma lista de alimentos vindos do banco de dados

@Dao
interface AlimentoDaoRoom {

    @Query("SELECT * FROM alimento")
    suspend fun buscarTodos(): List<Alimento>

O problema é que estou envolvendo a chamada do método em uma coroutine:

lifecycleScope.launch {
            alimentos = dao.buscarTodos().toMutableList()
        }

E essa lista de alimentos é repassada para um adapter de uma combo box (spinner)

adapter = ArrayAdapter<Alimento>(
            this,
            R.layout.spinner_item,
            alimentos
        )

Mas como a inicialização da variável 'alimento' é feita dentro de uma coroutine ela tem uma certa demora, e por isso quando chega no adapter recebo um erro dizendo que a variável alimento ainda não foi inicializada "lateinit property alimentos has not been initialized"

Como faço pra inicialização do adapter acontecer só depois que a variável 'alimento' receber a lista do banco de dados?

obrigado quem puder ajudar !!

7 respostas

Ley, tudo bem ?

Cara nesse cenário tu poderia usar um Flow de coroutines e pegar os dados sendo um LiveData na sua tela, assim você resolveria um pouco desse problema.

@Dao
interface AlimentoDaoRoom {

    @Query("SELECT * FROM alimento")
    fun buscarTodos(): Flow<List<Alimento>>

Na hora de consumir, pode fazer algo assim:

dao.buscarTodos().asLiveData().observe(this) { lista ->
   adapter = ArrayAdapter<Alimento>(
            this,
            R.layout.spinner_item,
            lista
        )

}

eae, matheus.

Vc tá sempre me ajudando com as dúvidas. vlw msm

No caso, meu app não foi construído com o padrão MVVM. Não estou usando livedata, observe, viewmodel etc

Será que teria outra forma? ^^"

Estamos aqui pra ajudar, só assim a gente evolui :)

Não tem problema não usar o MVVM, tá tranquilo, só vai ser um pouco diferente do que eu tinha proposto.

Você pode manter a ideia que eu falei no outro post, o que vai mudar é a ideia do live data apenas, no caso você vai precisar lançar um coroutine para pegar os dados e colocar na tela, algo assim:

lifecycleScope.launch {
            dao.buscarTodos().collect { lista ->
                     adapter = ArrayAdapter<Alimento>(
                                    this,
                                    R.layout.spinner_item,
                                    lista
                        )
            }
        }

cara, o código deixa de compilar se eu deixo o ArrayAdapter dentro do escopo do lifecycle : (

lifecycleScope.launch {
            dao.buscarTodos().collect {
                adapter = **ArrayAdapter**<Alimento>(
                    this,
                    R.layout.spinner_item,
                    it
                )
            }
        }

O ArrayAdapter fica sublinhado de vermelho com o aviso:

"None of the following functions can be called with the arguments supplied."

imagino que seja o this, você está dentro da coroutine, acredito que se colocar o this da activity ai, deve resolver

manow, mesmo envolvendo todos os métodos do DaoRoom em coroutines(que são muitos), continuo tomando exceção em vários pontos do código dizendo que as variáveis não estão sendo inicializadas. Que inferno.

O programa já nem funciona como antes. tá cheio de novos bugs. Informações que estão sumindo, lentidão etc

Vc tem algum material bom que ensine sobre coroutines? to entrando em depressão já

Rapaz, coroutines é algo bem maneiro, gosto bastante de ver as coisas da doc oficial

https://kotlinlang.org/docs/coroutines-overview.html https://developer.android.com/kotlin/coroutines

O lance é que a galera vai assumir que tu vai usar mvvm como padrão arquitetural...

Cara, além disso, eu sinceramente não peguei muito a ideia que tu tá levando esses erros, fiquei meio confuso nisso.

Talvez inicializar as coisas com um valor default, só pra evitar os erros já seja uma maneira paliativa de evitar essas dores de cabeça, embora não sei se pra tua lógica do app faz sentido isso.

Cara se quiser mostrar um pouco mais do código pra termos contexto e saber como te ajudar também pode ser uma boa :)

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software