#はじめに
Kotlin 1.1からCoroutineが実験的に組み込まれました。
Coroutineとは**「特定のスレッドに束縛されない、中断可能な計算インスタンス」**です。
非同期処理で用いられますが、Thread
よりも軽量で、実行途中で処理を中断・再開
することができます。
#準備
Coroutineを利用するために、build.gradle
に下記の情報を追記します。
今回は2018/09/30時点での最新版(0.30.0
)を使用しています。
更新状況はここから確認できます。
dependencies {
...
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0"
}
kotlin {
experimental {
coroutines 'enable'
}
}
repositories {
jcenter()
}
#使い方
Coroutineの作成にはCoroutineビルダー
を使用します。
##runBlocking
現在のスレッドをブロックするビルダーです。任意の型を返します。
runBlocking {
// 何かしらの処理
}
###Sample
fun main(args:Array<String>) {
println(1)
runBlocking {
println(2)
}
println(3)
}
/**
* 実行結果
* 1
* 2
* 3
*/
##launch
戻り値としてJob
を返すビルダーです。
0.26.1
からlaunch
がGlobalScope.launch
になりました。
GlobalScope.launch {
// 何かしらの処理
}
###Sample
現在のスレッドをブロックしないため、launch
内の処理が実行される前にプログラムが終了します。
fun main(args:Array<String>) {
println(1)
launch {
println(2)
}
println(3)
}
/**
* 実行結果
* 1
* 3
*/
引数で実行するスレッドを指定できます。
引数なしの場合はDispatchers.Defaultが設定されます。
0.26.1
からCommonPool
がDispatchers.Default
になりました。
0.26.1
からUI
がDispatchers.Unconfined
になりました。
/**
* Dispatchers.Default -> バックグラウンドスレッド
* Dispatchers.Unconfined -> メインスレッド
*/
GlobalScope.launch(Dispatchers.Unconfined) {
// 何かしらの処理
}
Job#join()
を利用すれば、呼び出し先のcoroutineの終了まで呼び出し元のcoroutineを中断できます。
runBlocking {
GlobalScope.launch() {
// 何かしらの処理
}.join()
}
###Sample
fun main(args:Array<String>) = runBlocking {
println(1)
GlobalScope.launch {
println(2)
}.join()
println(3)
}
/**
* 実行結果
* 1
* 2
* 3
*/
##async
戻り値としてDeferred<T>
を返すビルダーです。
Coroutineの処理が終わったタイミングで戻り値を取得できます。
0.26.1
からasync
がGlobalScope.async
になりました。
GlobalScope.async {
// 何かしらの処理
}
###Sample
launch
同様、現在のスレッドをブロックしないため、async
内の処理が実行されません。
fun main(args:Array<String>) {
println(1)
GlobalScope.async {
println(2)
}
println(3)
}
/**
* 実行結果
* 1
* 3
*/
Job#join()
同様、Deferred<T>#await()
を利用すれば、呼び出し先のCoroutineの終了まで呼び出し元のCoroutineを中断できます。
runBlocking {
GlobalScope.async {
// 何かしらの処理
}.await()
}
###Sample
fun main(args:Array<String>) = runBlocking {
println(1)
GlobalScope.async {
println(2)
}.await()
println(3)
}
/**
* 実行結果
* 1
* 2
* 3
*/
#Suspend関数
Coroutineを中断できる関数です。suspend
をつけることで宣言できます。
CoroutineかSuspend関数内からのみ実行できます。
suspend fun sampleSuspending(){
// 何かしらの処理
}
###Sample
delay
はSuspend関数なので実行できます。
fun main(args:Array<String>) = runBlocking {
println(1)
sampleSuspending()
println(3)
}
suspend fun sampleSuspending() {
delay(1000)
println(2)
}
/**
* 実行結果
* 1
* (1秒中断)
* 2
* 3
*/
#まとめ
非同期処理を直感的に理解しやすく、とても簡潔に記述できるようになりました。
#参考
[Coroutines - Kotlin Programming Language]
(https://kotlinlang.org/docs/reference/coroutines.html)
[AndroidでKotlin Coroutinesを使ってみる]
(http://tech.furyu.jp/blog/?p=6388)
[eaglesakuraの技術ブログ]
(https://eaglesakura.hatenablog.com/entry/2018/09/21/142152)
[Kotlin の Coroutine を概観する]
(https://qiita.com/kawmra/items/ee4acb7db61f70dec9a8)
[入門Kotlin coroutines]
(https://qiita.com/k-kagurazaka@github/items/8595ca60a5c8d31bbe37)