- Sealed sinif qurmaq və onu
else-sizwhenilə emal etmək suspend,launch,async/awaitvədelay-in rolunu izah etmək- Sadə
@Composablefunksiyası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.
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))
}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şqasuspendfunksiyadan ç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əniawait()ilə alırsan.runBlocking { }— adimainfunksiyasını korutinlər dünyası ilə birləşdirir; yalnız nümunələr və testlər üçündür.
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")
}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:
@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")
}@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.Columnelementlə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ə
whenonlarıelse-siz tam əhatə edə bilər. - Korutin axını bloklamadan dayana bilir;
suspendfunksiyalar yalnız korutinlərdən çağırılır. launchnəticəsiz iş başladır,asyncisə nəticə verir və onuawait()ilə almaq olar.- Compose-da interfeys
@Composablefunksiyalarla 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.
when ifadəsində niyə else lazım deyil?