Coroutine Builder — coroutine'leri oluşturan ve başlatan, yürütme şekillerini tanımlayan Kotlin Coroutines işlevleridir. launch, async, runBlocking ve produce oluşturucuları, arka plan görevlerinden sonuç döndüren paralel hesaplamalara kadar farklı senaryoları kapsar. JetBrains, 2024'e göre Coroutine Builder, yapılandırılmış eşzamanlılık ve yaşam döngüsü yönetimi sağlayarak coroutine modelinin temelidir.
Önemli Noktalar
Coroutine Builder, bir CoroutineScope ve bir suspend bloğu alarak yeni bir coroutine oluşturan ve başlatan bir Kotlin uzantı işlevidir. Her oluşturucu, coroutine'in nasıl yürütüleceğini tanımlar: sonuç döndürmeli veya döndürmesiz, iş parçacığı bloklamalı veya eşzamansız olarak. Oluşturucular, dilin coroutine modeline giriş noktalarıdır.
Tüm oluşturucular, alt coroutine'lerin yaşam döngüsünü yöneten CoroutineScope aracılığıyla çalışır. Bir kapsam iptal edildiğinde, bu kapsam üzerinden başlatılan tüm coroutine'ler otomatik olarak iptal edilir — bu yapılandırılmış eşzamanlılık ilkesidir. Bu yaklaşım, coroutine sızıntılarını önler ve öngörülebilir sonlandırma sağlar.
import kotlinx.coroutines.*
fun main() = runBlocking {
// Oluşturucular CoroutineScope içinde çalışır
val job = launch {
delay(1000L)
println("Dünya!")
}
println("Merhaba,")
job.join()
}
Kotlin dört yerleşik coroutine oluşturucu sağlar: launch, async, runBlocking ve produce. Her birinin kendi dönüş türü ve uygulama alanı vardır. Android mobil geliştirme için ana oluşturucular launch ve async'dir — bloklamayan şekilde çalışır ve mimari bileşenlerle entegre olur.
| Oluşturucu | Dönüş türü | İş parçacığı bloklama | Senaryo |
|---|---|---|---|
| launch | Job | Hayır | Fire-and-forget görevler |
| async | Deferred<T> | Hayır | Paralel hesaplamalar |
| runBlocking | T | Evet | Testler, main işlevi |
| produce | ReceiveChannel<E> | Hayır | Akış (kullanımdan kaldırıldı) |
Her oluşturucu ek parametreler kabul eder: CoroutineStart (başlatma stratejisi), CoroutineContext (dağıtıcı, istisnalar) ve adlandırılmış bir kod bloğu. Varsayılan olarak, coroutine hemen başlar (CoroutineStart.DEFAULT).
launch, Android geliştirmede en çok kullanılan oluşturucudur. Sonuç döndürmeyen bir coroutine başlatır ve yaşam döngüsünü yönetmek için bir Job nesnesi döndürür. Bu, yalnızca yan etki gerektiren işlemler için ideal seçimdir: veritabanına kaydetme, analitik gönderme, arayüz güncelleme.
launch oluşturucusu CoroutineScope, isteğe bağlı bir CoroutineContext ve bir suspend bloğu kabul eder. Döndürülen Job, coroutine'i iptal etmeye, tamamlanmasını beklemeye veya durumunu kontrol etmeye olanak tanır.
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
val data = fetchFromNetwork()
saveToDatabase(data)
}
job.start()
job.join()
CoroutineStart.LAZY parametresi, start() veya join() açıkça çağrılana kadar yürütmeyi erteler. Bu, gecikmeli başlatma ve koşullu yürütme için kullanışlıdır. Standart anında yürütme için CoroutineStart.DEFAULT kullanılır veya parametre atlanır.
async, Deferred<T> — bir sonucun eşzamansız vaadi döndüren oluşturucudur. await() çağrısı, iş parçacığını bloklamadan sonuç elde edilene kadar coroutine'i askıya alır. Bu, Kotlin coroutine'lerinde paralel görevler için birincil mekanizmadır.
async, birden çok bağımsız işlemi aynı anda yürütmeniz gerektiğinde özellikle etkilidir. Suspend işlevlerinin sıralı çağrılarının aksine, async coroutine'leri paralel olarak başlatarak toplam yürütme süresini azaltır.
suspend fun fetchUserData(): UserData {
val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
return UserData(
profile = deferred1.await(),
settings = deferred2.await(),
notifications = deferred3.await()
)
}
Deferred, Job'dan devralır, bu nedenle async tüm yaşam döngüsü işlemlerini destekler: iptal, tamamlanma bekleme, istisna işleme. Bir kapsam iptal edildiğinde, alt Deferred coroutine'leri otomatik olarak iptal edilir.
runBlocking, coroutine tamamlanana kadar geçerli iş parçacığını bloklayan tek oluşturucudur. Yeni bir CoroutineScope oluşturur ve iletilen coroutine'i başlatarak çağıran iş parçacığını bloklar. main() giriş noktalarında, testlerde ve bloklayan kodla entegrasyonda kullanılır.
runBlocking üç senaryoda haklıdır: uygulama giriş noktası (main), suspend işlevlerinin birim testleri ve suspend kullanılamayan geri arama tabanlı kütüphanelerle entegrasyon. Üretim Android kodunda, ana iş parçacığında runBlocking kullanımı kesinlikle önerilmez.
class CoroutineTest {
@Test
fun `test suspend function`() = runBlocking {
val result = mySuspendFunction()
assertEquals("expected", result)
}
}
Testler için runBlocking yerine TestCoroutineDispatcher ile kotlinx-coroutines-test kullanılması önerilir — bu, zaman kontrolü sağlar ve test ortamında bloklamayı önler.
Coroutine Builder seçimi, döndürülen sonuca ve yürütme senaryosuna bağlıdır. İşlem veri döndürmeyi gerektirmiyorsa — launch kullanın. Eşzamansız bir işlemin sonucuna ihtiyacınız varsa — async kullanın. runBlocking yalnızca köprüleme için kullanılmalı ve reaktif akışlar için produce'u Flow ile değiştirin.
Kotlin Coroutines kullanan Android projelerinde ana oluşturucu çifti launch ve async'dir. launch, ViewModel ve UseCases'te coroutine başlatmak için kullanılırken, async ağ veya veritabanına paralel istekler için kullanılır. Modern kütüphaneler (Ktor, Room) zaten suspend işlevlerini destekler, bu da async'in doğrudan kullanım ihtiyacını en aza indirir.
Sıkça Sorulan Sorular
launch Job döndürür ve yürütme sonucu döndürmezken, async Deferred<T> döndürür — await() ile sonucun alınabileceği bir nesne. launch fire-and-forget işlemleri için, async veri döndüren görevler için kullanılır.
Önerilmez. Ana iş parçacığında runBlocking ANR'ye neden olur ve arayüzü bloklar. Activity ve Fragment içinde lifecycleScope.launch kullanın — bu, bloklama olmadan yerleşik bir çözümdür.
launch oluşturucusu, coroutine yaşam döngüsünü kontrol etmeye olanak tanıyan bir Job nesnesi döndürür: iptal (cancel), tamamlanma bekleme (join), durum kontrolü (isActive, isCompleted, isCancelled).
Deferred<T>, async oluşturucusu tarafından döndürülen bir sonucun eşzamansız vaadidir. Job'dan devralır ve şu yöntemleri ekler: sonuç almak için await(), bloklamayan erişim için getCompleted() ve istisna kontrolü için getCompletionExceptionOrNull().
CoroutineStart.LAZY parametresini kullanın: scope.launch(start = CoroutineStart.LAZY) { ... }. Ardından gerçek yürütme için job.start() veya job.join() çağrısı yapın. Bu, gecikmeli başlatma ve koşullu coroutine yürütme için kullanışlıdır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun