Android'de Coroutine Kullanırken Main Thread'i Neden Tıkarsın
Coroutine'i öğrenince çoğu geliştirici bir yanılgıya düşüyor: "Coroutine non-blocking, o zaman Main thread'i rahat rahat kullanabilirim." Sonra uygulamada UI donuyor, frame düşüyor, kullanıcı "bok gibi app" diyor. Hata Coroutine'de değil, onu yanlış yerde kullanmakta.
Coroutine asenkron değildir, suspensibl'dır. Fark önemli. Bir coroutine Main thread üzerinde çalışabilir ve çalışır da, eğer siz `launch(Dispatchers.Main)` veya hiç dispatcher belirtmezseniz. Yani şu kodu yazdığında:
1viewModelScope.launch {2val data = fetchData() // Ağır işlem3updateUI(data)4}Bu kodu çalıştırdığında `fetchData()` Main thread'i bloke ediyor. Coroutine suspend olmuyor, çünkü `fetchData()` suspend function değil. Eğer normal bir fonksiyon, API çağrısı veya veritabanı sorgusu ise, thread orada bekliyordur.
Doğru yol: ağır işleri `Dispatchers.IO` veya `Dispatchers.Default`'a taşı.
1viewModelScope.launch {2val data = withContext(Dispatchers.IO) {3fetchData() // Arka planda çalışır4}5// Buraya döndüğünde Main thread'desiniz6updateUI(data)7}Bu şekilde `fetchData()` IO thread pool'unda çalışırken, Main thread boş ve responsive kalır.
İkinci yaygın hata: suspend function içinde blocking işlem yapmak. Retrofit, Room veya başka bir kütüphane zaten suspend fonksiyon sağlıyorsa, o fonksiyonu direkt çağır. Eğer kütüphane suspend fonksiyon sunmuyorsa, işlemi `withContext(Dispatchers.IO)` içine al. `runBlocking` kullanma, Main thread'i kilitler.
Üçüncü: `GlobalScope.launch` veya `MainScope().launch` ile lifecycle'ı umursamayan coroutine açmak. Activity destroy olduğunda coroutine çalışmaya devam eder, memory leak yaşarsın. Daima `viewModelScope`, `lifecycleScope` veya `lifecycleScope.launchWhenStarted` kullan.
Coroutine'in gücü thread'leri değiştirmekte, Main thread'i boş tutmakta ve kod akışını doğal tutmaktadır. Ama bunu sağlamak için dispatcher'ları doğru kullanman gerekir. Coroutine sadece suspend etme mekanizması sunar; blocking işlemi arka plana taşıyan sen olursun.
0 yorum