eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

coroutines 0.24.x runBlockingの仕様変更と対策

変更されたこと

  • runBlockingがUIスレッドからの呼び出しで例外を投げるようになった
    • UnitTestの内部とかで使ったり、無理矢理coroutinesのChannelとかを待ち合わせる用途に使えなくなった
  • 特にJVMでのUnitTestで使ってたので、全部死んだ
// この呼び出しはすべて例外となる
// 23.x系列までは使える
// 24.x系列からは駄目

@Test
fun testHogeFuga() = runBlocking { /* do something */ }

runBlockingの仕様変更に関するissue

issue Support runBlocking for UI Tests

  • コレは意図した変更なので、多分不可逆じゃないかな、とは思う
  • coroutineの処理実装から考えると、特定のシングルスレッドをブロックするのは好ましくない
    • 待機しているcoroutineの処理ブロックが回らなくなる

解決方法

// 最初に呼び出す
init {
    System.setProperty(BLOCKING_CHECKER_PROPERTY_NAME, BLOCKING_CHECKER_VALUE_DISABLE)
}
  • もしくは0.23.x系列までを使用する
  • もしくはUIスレッド対応のrunBlockingを用意する
  • さらに面倒をするなら、BlockingCheckerを自前で実装してそちらを使うように迂回させる
    • この方法は用意されてるけども面倒なのでskip

CoroutineScope.coroutineContextが非推奨

  • suspendブロック内のthis.coroutineContextが非推奨になった
  • トップレベルプロパティとして kotlin.coroutines.experimental.coroutineContext が生まれているので、それを利用する