Məzmuna keç
Educora
İrəli22 dəq8 / 14

Sealed siniflər, korutinlər və Jetpack Compose

Müasir Android tətbiqinin üç əsas alətini tanı: vəziyyətləri sealed siniflərlə təsvir et, işləri korutinlərlə ekranı dondurmadan gör və interfeysi Jetpack Compose ilə qur.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Sealed sinif qurmaq və onu else-siz when ilə emal etmək
  • suspend, launch, async/await və delay-in rolunu izah etmək
  • Sadə @Composable funksiyasını oxumaq və vəziyyət dəyişəndə ekranın necə yeniləndiyini başa düşmək

Mesajlaşma tətbiqini açırsan: əvvəlcə fırlanan yüklənmə işarəsi görünür, sonra mesajlar, internet yoxdursa isə xəta bildirişi. Bu müddətdə ekran donmur — siyahını sürüşdürə, düymələrə basa bilərsən. Bunun arxasında Kotlin-in üç imkanı dayanır: vəziyyətləri təsvir edən sealed siniflər, arxa planda iş görən korutinlər və ekranı çəkən Jetpack Compose. Bu dərs Android dünyasına ilk addımındır.

Sealed siniflər: qapalı ailə

Sealed («möhürlənmiş») sinfin bütün törəmə sinifləri əvvəlcədən məlumdur və eyni paketdə elan olunur — başqa yerdə yeni törəmə sinif yaratmaq olmaz. Bu, «yüklənir / uğurlu / xəta» kimi sabit variantlar toplusunu təsvir etmək üçün idealdır. Variantların hər biri öz məlumatını saxlaya bilər: xətada səbəb, uğurda nəticə. Məlumatsız variant üçün data object işlədilir.

Kotlin
sealed class UiState {
    data object Loading : UiState()
    data class Success(val messages: Int) : UiState()
    data class Error(val reason: String) : UiState()
}

fun render(state: UiState): String = when (state) {
    UiState.Loading -> "Loading..."
    is UiState.Success -> "You have ${state.messages} new messages"
    is UiState.Error -> "Error: ${state.reason}"
}

fun main() {
    val states = listOf(UiState.Loading, UiState.Success(5), UiState.Error("No internet"))
    states.forEach { println(render(it)) }
    println(UiState.Success(5))
}
Gözlənilən nəticə
Loading...
You have 5 new messages
Error: No internet
Success(messages=5)

Diqqət et: when ifadəsində else budağı yoxdur. Kompilyator UiState-in yalnız üç variantı olduğunu bilir və hamısının yoxlandığına əmin olur. is UiState.Success budağında isə ağıllı tip çevrilməsi işləyir — state.messages birbaşa əlçatandır.

Korutinlər: dondurmadan gözləmək

Android tətbiqində ekranı əsas axın (main thread) çəkir. İnternetdən məlumat yükləmək bir neçə saniyə çəkə bilər; bu vaxt əsas axın gözləsə, ekran donar. Korutinlər bu problemi həll edir: korutin işin ortasında dayana (suspend), axını başqa işlərə buraxa və cavab gələndə davam edə bilər. Korutinlər çox yüngüldür — minlərlə korutin eyni vaxtda işləyə bilər.

  • suspend fun — dayana bilən funksiya. Onu yalnız korutinin içindən və ya başqa suspend funksiyadan çağırmaq olar.
  • delay(1000) — korutini 1 saniyəliyə dayandırır, amma axını bloklamır.
  • launch { } — nəticə gözlənilməyən yeni korutin başladır («başlat və unut»).
  • async { } — nəticə qaytaran korutin başladır; nəticəni await() ilə alırsan.
  • runBlocking { } — adi main funksiyasını korutinlər dünyası ilə birləşdirir; yalnız nümunələr və testlər üçündür.
Kotlin
import kotlinx.coroutines.*

suspend fun fetchTemperature(city: String): Int {
    delay(1000)
    return if (city == "Baku") 24 else 19
}

fun main() = runBlocking {
    println("Loading...")
    launch {
        delay(500)
        println("Half a second passed")
    }
    val baku = async { fetchTemperature("Baku") }
    val ganja = async { fetchTemperature("Ganja") }
    println("Baku: ${baku.await()}, Ganja: ${ganja.await()}")
    println("Done")
}
Gözlənilən nəticə
Loading...
Half a second passed
Baku: 24, Ganja: 19
Done
kotlinx-coroutines-core kitabxanası lazımdır. İki sorğu paralel işlədiyi üçün proqram 2 yox, təxminən 1 saniyə çəkir.

Android-lə ilk tanışlıq: Jetpack Compose

Jetpack Compose Android interfeyslərini Kotlin kodu ilə qurmaq üçün Google-un müasir alət dəstidir. Ekranı addım-addım dəyişdirmək əvəzinə, onun necə görünməli olduğunu təsvir edirsən — bu yanaşma deklarativ adlanır. Ekranın hər hissəsi @Composable annotasiyası ilə işarələnmiş adi Kotlin funksiyasıdır. Aşağıdakı kod Android layihəsinin bir hissəsidir, onu ayrıca proqram kimi işə salmaq olmaz:

Kotlin
@Composable
fun Greeting(name: String) {
    var count by remember { mutableIntStateOf(0) }

    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "Hello, $name!")
        Button(onClick = { count++ }) {
            Text("Clicked $count times")
        }
    }
}

@Preview
@Composable
fun GreetingPreview() {
    Greeting("Aysel")
}
Nəticə: «Hello, Aysel!» yazısı və altında düymə; hər basışda düymədəki say 1 artır.
  • @Composable — bu funksiyanın interfeysin bir hissəsini təsvir etdiyini bildirir. Belə funksiyaların adları böyük hərflə başlayır: Greeting.
  • remember { mutableIntStateOf(0) } — vəziyyət (state) yaradır: Compose onun qiymətini yadda saxlayır və izləyir.
  • Column elementləri şaquli düzür, Modifier.padding(16.dp) kənarlardan boşluq verir.
  • Button(onClick = { count++ }) { ... } — tanış mənzərə: iki lambda! Biri basışda işləyir, ikincisi (sonuncu lambda) düymənin içini təsvir edir.
  • @Preview — Android Studio-ya bu ekranın önizləməsini tətbiqi telefonda işə salmadan göstərməyə imkan verir.

Sehr haradadır? Düyməyə basanda count dəyişir. Compose bunu görür və Greeting funksiyasını yenidən çağırır — bu, yenidən kompozisiya (recomposition) adlanır — və ekranda yalnız dəyişən hissəni yeniləyir. Sən ekranı əl ilə yeniləmirsən, sadəcə vəziyyəti dəyişirsən. Keçən dərslərin hamısı burada birləşir: funksiyalar, lambdalar, sətir şablonları, when ilə vəziyyətlər.

Əsas fikirlər

  • Sealed sinfin bütün variantları məlumdur, ona görə when onları else-siz tam əhatə edə bilər.
  • Korutin axını bloklamadan dayana bilir; suspend funksiyalar yalnız korutinlərdən çağırılır.
  • launch nəticəsiz iş başladır, async isə nəticə verir və onu await() ilə almaq olar.
  • Compose-da interfeys @Composable funksiyalarla təsvir olunur; vəziyyət dəyişəndə ekran avtomatik yenilənir (recomposition).

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Sealed sinif üzərində when ifadəsində niyə else lazım deyil?