Tema
/
Mobiliosios programėlės KOTLIN
Pamoka 5 / 14 Backend ir Retrofit ~50 min

Sujunk grandinę — repo → VM → ekranas (iš apačios į viršų)

Dabar sujungiam visą grandinę: repozitorija → ViewModel → ekranas. Penki failai kodo stulpelyje kaip skirtukai — kurk iš apačios į viršų (data → presentation), tokia tvarka, kokia jie yra. Sukursi ViewModel prieš repozitoriją — gausi keturias kompiliavimo klaidas ir jokio supratimo kodėl; priklausomybė teka viena kryptimi.

1. MenuRepository.kt (data) — plonas sluoksnis: gauna DTO iš PicaApi, grąžina švarų domeninį MenuItem. getMenu() yra suspend (vienas tinklo kvietimas). 7 pamoka paverčia jį Room talpykla.

2. MenuEvent.kt (presentation) — kas gali nutikti: LoadMenu, Retry.

3. MenuUiState.kt (presentation) — tinklo būsenos kaip sealed interface, lygiai tokia forma, kokią krepšelis mokė 3 pamokoje, tik tinklo kvietimui:

sealed interface MenuUiState {
    data object Loading : MenuUiState
    data class Success(val items: List<MenuItem>) : MenuUiState
    data class Error(val message: String) : MenuUiState
}

4. MenuViewModel.kt (presentation) — init { onEvent(LoadMenu) } kraunasi automatiškai; kraunant rodo Loading, tada Success(items) arba Error.

5. MenuScreen.kt (modify) — 2 pamokos ekranas nebepriima statinio List<MenuItem>; jis priima ViewModel, stebi jo būseną ir piešia when (state). Kortelė iš 2 pamokos nepakitusi perkelta į Success šaką — pasikeitė tik duomenų šaltinis.

Retrofit RANKOMIS (dar be Koino — tai 6 pamoka). Vis tiek reikia gyvo PicaApi. Kol kas grandinę statyk pats kvietimo vietoje — tai laikina jungtis, kurią 6 pamoka pašalina:

// LESSON 5: surišta ranka. 6 pamokoje Koinas visa tai pakeis.
object Network {
    private val json = Json { ignoreUnknownKeys = true }
    private val retrofit = Retrofit.Builder()
        .baseUrl("http://10.0.2.2:8080/")   // emuliatorius → tavo localhost:8080
        .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
        .build()
    val api: PicaApi = retrofit.create(PicaApi::class.java)
}

// kur rodomas MenuScreen, paduok jam ViewModel iš grandinės:
MenuScreen(menuViewModel = viewModel { MenuViewModel(MenuRepository(Network.api)) })

Patikrink. Paleisk backendą (localhost:8080), tada programėlę emuliatoriuje. Turi:

Trumpam:  ⟳ (Loading)
Tada:     tikras picų sąrašas iš serverio (GET /menu)

Meniu picos dabar ateina iš serverio, ne iš kodo.

Spąstai (CLEARTEXT). Jei backendas veikia per paprastą http (ne https, kaip lokalus 10.0.2.2:8080), pirmas paleidimas nulūžta:

java.net.UnknownServiceException: CLEARTEXT communication to 10.0.2.2
not permitted by network security policy

Android nuo tam tikros versijos blokuoja nešifruotą http. Kūrimui leidžiam jį AndroidManifest.xml (tik debug!):

<application android:usesCleartextTraffic="true" ... >

(Švaresnis būdas — network_security_config.xml tik 10.0.2.2 adresui.) Produkcijoje serveris turi būti https — tada šito nereikia. Įdėjęs — paleisk iš naujo; meniu užsikraus.