--- title: 【Android/kotlin】コルーチン tags: android --- # 【Android/kotlin】コルーチン Androidプロジェクトでコルーチンを使用するには,アプリのbuild.gradleファイルに次の依存関係を追加する. ``` dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' } ``` # コルーチンとは Coroutinesとは,処理を途中で中断して,続きから処理を再開できる処理のまとまり(関数)のことである.数秒後に何か処理を行いたいときや,非同期処理に使用する. # サブルーチンとの違い サブルーチン(通常の関数)は,開始するとリターンまでが一気に実行されるが,コルーチンは処理の途中で中断,再開が可能である. # コルーチンの全体像について 以下のサイトが参考になる. - https://qiita.com/offwhite/items/94540e7cc3b330507c9c - https://qiita.com/kawmra/items/d024f9ab32ffe0604d39 # コルーチンを実際に使ってみる 順序としては,まず,スコープを作り,次に,コンテキスト(Dispatcher(コルーチンをどのスレッドで実行するか),Job)を設定して,コルーチン(Job)を作成する.Dispatcherはおもに以下の種類がある. | Dispacher | 説明 | | -------- | -------- | | `Dispatchers.Main` | Main Threadを指定する | | `Dispatchers.Default` | バックグラウンドスレッドの共有プールを利用する。スレッド最大数はCPUコアの数となる。基本的に非同期で何らかの計算をする際に使用する. | | `Dispatchers.IO` | オンデマンドで追加のスレッドが立つ。デフォルトでは64スレッドかCPUコア数のどちらか大きい方となる。通信をする場合に使用する. | また,コルーチンの作成には,コルーチンビルダーを使用する.基本的なコルーチンビルダーは以下の通りである. - launch - async では,実際にAndroidのアプリに実装してみる. ```kotlin class SplashActivity : AppCompatActivity() { private lateinit var job: Job private lateinit var scope: CoroutineScope override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_splash) // 全てのコルーチンはこのjobの子になる job = Job() // スコープの作成.同時にコンテキストを設定 scope = CoroutineScope(job + Dispatchers.Main) // scopeのコンテキストを引き継ぎ,Jobだけは引き継がれず,自身のコルーチンになる // Dispatcherは,コンテキストを引き継ぐため,Dispatchers.Mainを使用している scope.launch { // コルーチンでの処理を2秒間中断し,UI側に制御を渡す withContext(Dispatchers.Default) { delay(2000) } val intent = Intent(applicationContext, MainActivity::class.java) startActivity(intent) } } override fun onDestroy() { super.onDestroy() job.cancel() } } ``` # suspendキーワード delay関数は,Suspending Functionと呼ばれるもので,途中で中断可能な関数である.普通の関数は,途中で中断をしたり,再開をすることはできない.また,Suspending FunctionはCoroutineの内部(または他の suspend function 内部)でしか使用できない.Suspending Functionは,自分で定義することもできる.ここでは,doSomethingというSuspending Functionを定義している. ```kotlin class SplashActivity : AppCompatActivity() { private lateinit var job: Job private lateinit var scope: CoroutineScope override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_splash) job = Job() scope = CoroutineScope(job + Dispatchers.Main) scope.launch { // Suspending Functionを呼び出す doSomething() } } // Suspending Functionは,Coroutine内または他のSuspending Function内からしか呼び出すことができない suspend fun doSomething() { // Suspending Functionの中ではSuspending Functionしか使えない // delayは,実はSuspending Functionである delay(1000) println("something") } } ``` # コルーチンにおける注意事項 - 全てのコルーチンはスコープ内で実行する必要がある.CoroutineScopeにより,1つ以上の関連するコルーチンを管理する - suspendキーワードは,Kotlin独自のもので,関数がコルーチン内から呼び出されるようにするものである # パターン&アンチパターン 以下のサイトが参考になる. - https://qiita.com/ikemura23/items/fb8caeba4c35fcd85644