LifecycleCoroutineScope を可視化しよう

# はじめに

- [`LifecycleCoroutineScope`](https://developer.android.com/reference/kotlin/androidx/lifecycle/LifecycleCoroutineScope) は `Coroutine`に用意された、非同期処理の範囲を制限するための機能になります。
- その名の通りライフサイクルに依存できるので、各メソッドがどのような範囲で挙動するか可視化してみました。


## 前提条件
- Android Studio 3.5.1 で確認しました。
- AndroidXは `androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-rc01` を利用しています。

## 確認する点
- `LifecycleCoroutineScope` の 以下のメソッドについて確認します。(基本となる `launch`も一緒に確認しています)
    - `launchWhenCreated`
    - `launchWhenStarted`
    - `launchWhenResumed`
    - `launch`

## 結果
|マーク|意味|
|---|---|
|○|対象ライフサイクルが発生した以降に処理が実施される|
|☓|対象ライフサイクルが発生した以降に処理が実施されない|
|-|確認不要（アプリ終了後）|

### Launch

|Lifecycle|launch|
|---|---|
|onCreate|○|
|onStart|○|
|onResume|○|
|onPause|○|
|onStop|○|
|onDestroy|-|

### launchWhenCreated

|Lifecycle|launch|
|---|---|
|onCreate|○|
|onStart|○|
|onResume|○|
|onPause|○|
|onStop|○|
|onDestroy|-|

### launchWhenStarted

|Lifecycle|launch|
|---|---|
|onCreate|☓|
|onStart|○|
|onResume|○|
|onPause|○|
|onStop|☓|
|onDestroy|-|

### launchWhenResumed

|Lifecycle|launch|
|---|---|
|onCreate|☓|
|onStart|☓|
|onResume|○|
|onPause|☓|
|onStop|☓|
|onDestroy|-|


### まとめ
- メソッドの説明には `The returned [Job] will be cancelled when the [Lifecycle] is destroyed.`とありますが、キャンセルのタイミングもライフサイクルのイベントに依存していますね。
- 使用したい処理の内容やタイミングでうまく使い分けると良いでしょう。

### 最後にコードを載せておきます。（たいした処理はしていませんが）
``` MainActivity.kt
class MainActivity : AppCompatActivity() {

    private val loopTime : Long = 1000
    private val handler = Handler()
    private val task = object : Runnable {
        override fun run() {
            outputLog()
            handler.postDelayed(this, loopTime)
        }
    }

    private fun outputLog(){
        lifecycleScope.launch { Log.d("Test","Action : lifecycleScope.launch") }
        lifecycleScope.launchWhenCreated { Log.d("Test","Action : lifecycleScope.launchWhenCreated") }
        lifecycleScope.launchWhenResumed { Log.d("Test","Action : lifecycleScope.launchWhenResumed") }
        lifecycleScope.launchWhenStarted { Log.d("Test","Action : lifecycleScope.launchWhenStarted") }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Test","lifecycle : onCreate")
        setContentView(R.layout.activity_main)
        handler.postDelayed(task, 0)
        outputLog()

        // 次のアクティビティーを表示
        button.setOnClickListener {
            val intent = Intent(this, MainActivity2::class.java)
            startActivity(intent)
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d("Test","lifecycle : onStart")
        outputLog()
    }

    override fun onPause() {
        super.onPause()
        Log.d("Test","lifecycle : onPause")
        outputLog()
    }

    override fun onResume() {
        super.onResume()
        Log.d("Test","lifecycle : onResume")
        outputLog()
    }

    override fun onStop() {
        super.onStop()
        Log.d("Test","lifecycle : onStop")
        outputLog()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("Test","lifecycle : onDestroy")
        outputLog()

        handler.removeCallbacks(task)
    }
}

```

これからも、良いアプリ開発を目指して:dancers: