Qiita初投稿です。何か間違い等ありましたらコメントで指摘いただけると助かります。
coroutineを使う際にDispatcherとして指定できるDispatchers.Main.immediateについて調べたことをまとめてみました。
要点
先に要点を述べておきます。
Dispatchers.Main.immediateとは?
- メインスレッドで実行される。
- UI更新を即時行いたい際に使用。
名前から予想できますがメインスレッドで実行されます。本記事では2つ目の「UI更新を即時行いたい際に使用」に焦点を当てて解説していきます。
調べた経緯
viewModelScopeを使う際に、デフォルトのDispatcherは何だろうと思い、ソースコードを見てみると以下のようになっていました。
val ViewModel.viewModelScope: CoroutineScope
get() {
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
return setTagIfAbsent(JOB_KEY,
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate))
}
DispatcherとしてDispatchers.Main.immediateが指定されています。
私はDispatcherとして指定できるものは以下の4種類だけだと思っていたので、Dispatchers.Main.immediateについて調べてみました。
- Dispatchers.Main
- Dispatchers.Default
- Dispatchers.IO
- Dispatchers.Unconfined
Qiita内でDispatchers.Main.immediateで検索すると以下の2つの記事がヒットします。
Coroutines私的メモ2~Dispatchers, withContext, async/await~
Kotlin coroutine入門 ② ~ coroutine scope & jobについて~
両記事ともDispatchers.Main.immediateの説明として以下のような記述がありました。
UI更新を即時行いたい際に使用
UI更新を即時行いたい際に使用とはつまりどういうことでしょうか?
Dispatchers.Mainではダメなのでしょうか?
UI更新を即時行いたい際に使用とはどういうことか
同様の処理をDispatchers.Mainを指定した場合とDispatchers.Main.immediateを指定した場合で比較して見ていきます。
Dispatchers.Mainの場合
メインスレッド上で以下の処理をした場合の出力を考えていきます。
Log.i("tag", "a")
launch(Dispatchers.Main){
Log.i("tag", "b")
}
Log.i("tag", "c")
出力
I/tag: a
I/tag: c
I/tag: b
a→c→bと出力されました。これはメインディスパッチャーが処理をMessage Queueにpostするだけでその場で実行されないからだそうです。
Dispatchers.Main.immediateの場合
Log.i("tag", "a")
launch(Dispatchers.Main.immediate){
Log.i("tag", "b")
}
Log.i("tag", "c")
出力
I/tag: a
I/tag: b
I/tag: c
a→b→cと出力されました。launch内の処理がその場で実行されていることがわかります。
つまり、Dispatchers.Main.immediateを指定したものをメインスレッド上で呼び出すと後続の処理を待たずしてコルーチン内の処理を実行できるということです。
そのため、コルーチン内にUI更新の処理がある場合は即座に画面に反映することができるという点から「UI更新を即時行いたい際に使用」ということなんだと考えられます。
参考にしたページ
Coroutines私的メモ2~Dispatchers, withContext, async/await~
Kotlin coroutine入門 ② ~ coroutine scope & jobについて~
MainCoroutineDispatcher.immediate - kotlinx-coroutines-core
Launching a Kotlin Coroutine for immediate execution on the Main thread