5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Kotlin coroutine入門①

Last updated at Posted at 2020-03-05

この記事を書く背景

coroutineとはなんぞやとか、書き方とかなんとなく勉強をしていたのですが、仕事でとうとうRxやめてcoroutineを使うことになったので色々参考にしつつ入門します。

coroutineとは

引用させてもらいます。

coroutineとは何かを一言で表現すると、「中断可能な計算インスタンス」になります。ここでいう計算インスタンスとは、 Thread クラスのインスタンスのように特定のコードブロックが紐付いたインスタンスのことです。coroutineもインスタンスを作成し、紐付いたコードブロックを実行するという点では Thread と同じです。しかし、一度 start したらそのまま最後までコードブロックが実行される Thread とは異なり、coroutineは実行の途中で処理を中断することができ、またその中断したところからそのままの状態で実行を再開することができます。

なんとなく理解できたが、聞きなれない単語が出てきた。
そもそも中断可能とは?

↓この辺りがjavaの動きから、coroutineの仕組みを学習できました m(_ _)m

Kotlin コルーチンの「中断」とは何なのか

Kotlinコルーチンを理解しよう

Rxとの比較

coroutineはRxJavaの代替ではありません。coroutineは前述のように「中断可能な計算インスタンス」ですが、RxJavaは「データフローを宣言的に書くリアクティブプログラミング用フレームワーク」です。こうして並べてみると比べるものではないことは一目瞭然ですが、それでは何故比較されているかといえば、RxJavaはPromiseパターンのスーパーセットでもあり、coroutineはPromiseパターンを同期的に書く手法(async/awaitパターン)を提供しているからです。特にAndroid開発においては標準の非同期処理の手法が使いづらかったため、RxJavaはリアクティブプログラミングのためにではなく、単なるPromiseとして活用されているケースが多くありました。そのようなケースにおいては確かにasync/awaitは代替となりうることから、本来同じ抽象レイヤーにいないこの2者が比較されることになったのです。最近は有識者による啓蒙活動によりこの誤解は解けつつありますが、きちんと理解しておきたいポイントです。

coroutineとは何でないのか

確かに使い所は似ているけれど、概念的な部分では別のレイヤーにある気がします。

サンプルアプリの作成

実際にサンプルコードを作って動かしていきたいと思います。

環境

runBlocking

code

現在のスレッドをブロックするビルダーです。任意の型を返します。

public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T {
       Log.d(TAG,"1")
        runBlocking {
            Log.d(TAG,"2")
        }
       Log.d(TAG,"3")
D/CoroutineSampleActivity: 1
D/CoroutineSampleActivity: 2
D/CoroutineSampleActivity: 3

launch

code

現在のスレッドをブロックしないため、現在のスレッドの処理が先に行われ、launch内の処理が後で実行されプログラムが終了します。

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job 
        Log.d(TAG,"4")
        GlobalScope.launch {
            Log.d(TAG,"5")
        }
        Log.d(TAG,"6")
 D/CoroutineSampleActivity: 4
 D/CoroutineSampleActivity: 6
 D/CoroutineSampleActivity: 5

join

コルーチン内で他のコルーチンの終了を待機するために Job#join が利用できます。

code

        runBlocking {
            Log.d(TAG,"7")
            GlobalScope.launch {
                Log.d(TAG, "8")
            }.join()
            Log.d(TAG,"9")
        }
 D/CoroutineSampleActivity: 7
 D/CoroutineSampleActivity: 8
 D/CoroutineSampleActivity: 9

async & await

async の返す Deferred インタフェースには await メソッドが定義されています。
await メソッドは、 async が起動したコルーチンの終了まで現在のコルーチンを中断し、終了したコルーチンの戻り値を取得します。

code

public fun <T> CoroutineScope.async(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T
): Deferred<T> 
  runBlocking {                          
      Log.d(TAG,"10")                   
      async {                            
          Log.d(TAG, "11")              
      }.await()                         
      Log.d(TAG,"12")                   
  }                                     
D/CoroutineSampleActivity: 10
D/CoroutineSampleActivity: 11
D/CoroutineSampleActivity: 12

suspend

suspend modifier を付けて関数を宣言することで、その関数が Coroutine を中断可能であることを示すことができます。
suspend と宣言された関数は Coroutine 内または他の Suspending Function 内からしか呼び出すことができません。
また Coroutine を開始するには最低 1 つの Suspending Function がなければなりません。

suspend fun getProfile(){
           delay(1000)
           Log.d(TAG,"getProfile")
    }
  runBlocking {
            async {
                getProfile()
            }.await()
        }
//1秒後に出力される
D/CoroutineSampleActivity: getProfile

次はKotlin coroutine入門 ② ~ coroutine scope & jobについて~

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?