Tema
/
Mobiliosios programėlės KOTLIN
Pamoka 7 / 14 Room kaip talpykla ~50 min

Papildyk MenuRepository.kt — talpykla + tinklas

Kodo stulpelyje — naujoji MenuRepository.kt. Palygink su 5 pamoka: ten buvo vienas getMenu(), einantis tiesiai į tinklą. Dabar getMenu() grąžina talpyklos Flow, o naujas refresh() atnaujina talpyklą iš tinklo (clearAll + insertAll). Konstruktorius dabar ima du dalykus: (api, dao).

Failo apačioje — atvaizdavimai tarp esybės ir domeno (abu turi price: Double, tad tiesioginiai):

private fun MenuItemEntity.toDomain() = MenuItem(id, name, description, price, category, imageUrl)
private fun MenuItem.toEntity() = MenuItemEntity(id, name, description, price, category, imageUrl)

MenuViewModel dabar stebi talpyklą IR paleidžia refresh() (abu init bloke):

init {
    observeMenu()   // prenumeruoja talpyklos Flow → Success iškart, jei kešas pilnas
    refresh()       // tinklas → talpykla → Flow automatiškai atsinaujina
}

private fun observeMenu() = viewModelScope.launch {
    repository.getMenu().collect { items ->
        if (items.isNotEmpty()) _uiState.value = MenuUiState.Success(items)
    }
}

private fun refresh() = viewModelScope.launch {
    try { repository.refresh() }
    catch (e: Exception) {
        if (_uiState.value !is MenuUiState.Success)      // klaidą rodom tik jei nėra keše
            _uiState.value = MenuUiState.Error(e.message ?: "Could not load menu")
    }
}

Ir Koinas — talpykla tampa keliais single, o MenuRepository gauna DAO:

// coreModule — DB ir DAO
single { Room.databaseBuilder(get(), PicaDatabase::class.java, "pica.db").build() }
single { get<PicaDatabase>().menuDao() }

// menuModule — MenuRepository dabar ima PicaApi IR MenuDao
single { MenuRepository(get(), get()) }               // get() = PicaApi, get() = MenuDao

Patikrink.

1. Paleisk online → meniu užsikrauna ir įsirašo į talpyklą.
2. Įjunk lėktuvo režimą, uždaryk ir vėl atidaryk → meniu VIS TIEK rodomas (iš talpyklos).
3. Grįžk online → refresh() tyliai atnaujina, jei serveryje kas pasikeitė.

Spąstai (main thread). Jei DAO metodas nėra suspend ar Flow, Room lūžta:

java.lang.IllegalStateException: Cannot access database on the main thread
since it may potentially lock the UI for a long period of time.

Room draudžia kreiptis į DB pagrindinėje (UI) gijoje — DB operacija gali užtrukti ir „užšaldyti" sąsają. Sprendimas — skaitymai Flow, rašymai suspend (mūsų DAO būtent toks). Niekada nedaryk sinchroninio @Query, grąžinančio List tiesiai.