Kotlin #4 | Coroutine'ler

Ego1st

Uzman üye
15 Mar 2018
1,109
25
Kotlin #4 | Coroutine Nedir? Örneklerle

Coroutine Nedir?

Coroutine, Kotlin'de Thread'leri yönetmemizi sağlayan, belli bir rutinde çalışan işler oluşturmamıza yarayan, async, await gibi Java'da onlarca satırda kodlanan işlemleri kolaylaştırmak için JetBrain ekibi tarafından geliştirilmiş bir yapıdır. Coroutine'ler aynı zaman Android Jetpack'in de bir parçasıdır.
Kotlin'de diğer dillerin Coroutine temelinin yanı sıra suspend function gibi yapıları getirerek, daha az hata ve daha güvenli bir ortam sağlıyor.

Kotlin, Coroutine gibi yapıların kütüphanesi manuel olarak dahil edilmesini sağlamak için kendi kitaplığında minimum düzeyde API bulundurur. Bu yüzden kullanmak istediğimizde 'kotlinx.coroutines' kütüphanesini aktif etmemiz gerekir.

Android Studio için Coroutine'i projemize dahil edelim.

build.gradle (app) dosyamızın içinde dependencies'in altına bunları ekleyelim

dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
}

Daha sonra kütüphane değişikliğimizin geçerli olması için Sync Now diyelim



İlk kodlarımızı yazmaya başlamadan önce bazı kavramları öğrenmemiz gerek.

1- Scope Nedir?

Scope, Türkçe anlamıyla alan, faaliyet alanı; Tam olarak programlamadaki anlamıyla eştir. Scope bir kodun çalıştığı alanı temsil eder. Scope seçimini düzgün yapmak önemlidir çünkü her zaman her yerde farklı scope'ları kullanmak gerekebilir.

Biz bir coroutine çalıştırdığımızda ve scope belirtmediğimizde kodu otomatik olarak Coroutine Scope'da çalıştırır. Coroutine Scope Nedir?

Coroutine Scope yeni coroutine için bir scope olarak tanımlanır coroutine'lerin default scope'udur. 'launch', 'run blocking' gibi kavramlar Coroutine Scope'a dahildir.

Global Scope ise bütün uygulamada çalışan üst level Coroutine scope'udur. Coroutine Scope'un aksine bütün yaşamdöngüsü boyunca çalışırlar.



Gördüğünüz gibi GlobalScope'da bir işlem çalıştırdık 100.000 defa a"ndroid" yazdırdık. Bu örnekte de gördüğünüz üzere launch'un içinde launch çalıştırabiliyoruz.



Gördüğünüz üzere Coroutine Scope ise bütün uygulamada çalışmadığı sadece belirtilen thread'de çalıştığı için tanımlanırken coroutine context belirtmemiz gerekiyor, burada "Dispatchers.Default", çalıştırılan kod güncel olarak hangi thread'deyse orada çalıştırılması manasına geliyor.

Burada yine delay kodunu kullandık delay gecikme demek burada değeri bizden milisaniye olarak alıyor o kadar süre bekliyor ve ondan sonra işlemi yapıyor.

Run Blocking Nedir?

Run Blocking güncel olan işlemleri durdurma, run blocking süresi dolana kadar ve içindeki işlem tamamlanana kadar hiçbir şey yapmama manasına geliyor. Gelin runblocking nasıl kullanılıyor ona bakalım



Şimdi diyebilirsiniz Run Blocking işlemine ne gerek var zaten delay ile geciktirebiliyorduk bunu ne zaman kullanalım? İşte şimdi Run Blocking'i ne zaman kullanmamız gerektiğini göreceğiz. Örneğimize bakalım

Thread & Coroutine Context Nedir?

Yukarıda da kısaca değinmiş olduğum üzere; Coroutine Context, Coroutine'in hangi thread'de işlem göreceğini belirtir



Gördüğünüz gibi launch'tan sonra thread belirtirsek Thread.currentThread() bize hangi thread'de olduğumuzu yansıtıyor. Bunun çıktısını görelim

2020-10-13 09:04:06.426 6646-6677/com.ego1st.coroutinekotlin I/System.out: Default Thread: DefaultDispatcher-worker-1
2020-10-13 09:04:06.427 6646-6678/com.ego1st.coroutinekotlin I/System.out: IO Thread: DefaultDispatcher-worker-2
2020-10-13 09:04:06.427 6646-6646/com.ego1st.coroutinekotlin I/System.out: Unconfined Thread: main

Gördüğünüz gibi default, io ve unconfined thread'lerin hepsi farklı dispatcher'larda çalışıyor. Tanımlamadığımız zaman ise otomatik olarak main thread'e atıyor.

Peki neden farklı Coroutine Context'leri kullanma ihtiyacı duyalım?

Farklı Coroutine Context'leri genellikle internetten bir aracı kütüphane olmadan indirirken kullanırız. Veriler I/O'da alınır böylece main thread bloklanmadan veri alınır daha sonra ise main'de işlenir.

Şimdi detaylı örneğimizi görmeden önce öğrenmemiz gerek birkaç kavram daha var onlar da Suspend Function ve Job Kavramları

Job Nedir?

Job, Türkçe anlamıyla iş; Kotlin'deki anlamına benziyor, Coroutine'i nasıl launch şeklinde çağırıyorsak burada da aynı şekilde fakat Job, Coroutine işlerinin değişken halidir. Ne demek istiyorum, bir örnekle görelim



Gördüğünüz gibi daha önceki Kotlin derslerinde gördüğümüz gibi val olarak tanımlayabiliyoruz. invokeOnCompletion metodu ile Job bittiğinde ne olacak onu söylüyoruz. Ve Job'u cancel yani iptal edebiliyoruz. İşte bunlar job tanımanın güzellikleri.

Suspend Function Nedir?

Suspend Function basitçe, istediğimiz zaman durdurup başlatabildiğimiz fonksiyonlara denir. Uzun süreli işlemlerde uygulamayı bloklamadan yapacağımız işlemler için kullanılır. Suspend Function sadece Coroutine içinde çağrılabilir.



Gördüğünüz gibi bir örnek kullanımı bu şekildedir.

Son olarak değinmemiz gereken bir kavram; Async

Async Nedir?

Async; asynchronous, Türkçe anlamıyla; asenkron, senkronize olmayan. Async işlemler main thread'i bloklayıp uygulamayı çökertmek istemediğimiz zaman kullandığımız kavramdır. Async işlemlerde bütün işlemler uygulamada olmaya devam ederken async altında belirtilen işlemlerde uygulamadaki işlemlerden bağımsız olmaya devam eder



Şimdi Coroutine'lerle ilgili öğrenmemiz gereken her şeyi öğrendik, şimdi hepsini kullandığımız bir örnek yapalım.



Öncelikle downloadNameData() ve downloadAgeData() isimli iki suspend fonksiyon oluşturduk. İki fonksiyonun içinde de bir süre beklettik değeri verdik ".. download" yazdırdık ve verdiğimiz değeri döndürdük. Normal bir internetten veri çekme işlemi daha uzun süreceği için bu işlemi thread'i bloklayan ve I/O'yu kullanan işlemler gibi düşünelim.

Gördüğünüz gibi downloadName ve downloadAge isimli async işlemler oluşturduk ve içinde internetten(!) verilerimizi çektik, unutmayın bunlar uygulamanın zaman akışından bağımsız.

Daha sonra kendi değerlerimizle indirdiğimiz değerleri eşleştirdik ama farketmişsinizdir burada .await() kullandık. await'i kullanmamızın sebebi async olduğu için ve zaman akışına göre ilerlemediği için biz o kod satırındayken o değer aslında geldi mi gelmedi mi bilmiyoruz await ise değer geldiği zaman eşitliyor ve bizi null değerlerden koruyor


Eğer içerik ile ilgili herhangi bir sorunuz varsa öm, ya da buradan sorabilirsiniz elimden geldiğince cevaplamaya çalışırım. İyi forumlar :))
 

Ghost Killer

Harici Saldırı Timleri Koordinatörü
13 Ocak 2019
11,318
7,706
Eline emeğine sağlık başarılı ve baya güzel bir konu olmuş.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.