kotlin-coroutines 0.26.1での破壊的更新
coroutines 0.26.1の変更点
- 多くのクラスやトップレベルfunctionやプロパティがdeprecatedになった
変更から見える方針
- トップレベルの関数やプロパティを、いずれかのobject等に所属させることが主な目的に見える
主なDeprecated
UI
,CommonPool
等の標準Dispatcherが非推奨Dispatchers.Main
,Dispatchers.Default
が追加された
launch{}
,async{}
等のトップレベル関数が非推奨GlobalScope.launch
,GlobalScope.async
が追加された
isActive
が拡張関数になった- ビルドが通らないので、ガイドに従って書き換える
互換性
- Deprecated属性になっただけで、0.24のときのような内部の破壊的仕様変更はされていない
- 様子見しつつ、移行して行こう。
移行時の注意
GlobalScope.launch
とCoroutineScope.launch
を使い分ける- CoroutineScope.thisが届く範囲のlaunch/async等はそのまま動作する
- 「とりあえずlaunchって書けば非同期になるよ」みたいなことが言えなくなる
- Android Studioの場合、
Alt + Enter
で移行先を示してくれるUI
をDispatchers.Main
にしてくれたり、いろいろ- デフォルト引数が設定されている場合、勝手にデフォルト値が転記されてしまうので、全自動は無理
- CommonPoolは補完されないので手動で
Dispatchers.Default
にする
withContext{}
で渡されるthisのスコープが変わった- ブロック内でフィールド変数にアクセスしてる場合、スコープ範囲外でエラーになる
this@HogeFuga.fieldName = Hoge
みたいに書き換える
悲観的推測
- GlobalScopeの場合とCoroutineScope.thisのLaunchでJobの親子関係が異なるかもしれない?
- ちゃんと移行しないと、
job.cancel()
の挙動とかに影響あるかも
- ちゃんと移行しないと、
- 0.24 -> 0.25のときのように破壊的変更が次期バージョンでRevertされる恐れもある
AS3.3 canary-11の問題点
問題点
- Find Action(Ctrl + Shift + A)が正常動作しない
- たまに正常動作する
- だいたい正常動作しない
- Crash Reportが吐き出されてるので、どっかのPluginと競合している
- Reportは送った
- 以前はFlutter Pluginと競合していたので、uninstall済み
- Dartも怪しかったのでuninstallしたが、改善されず
諦めた
- C12に期待する
CIや開発時のビルドタスク管理にfastlaneを導入した
導入前
導入した理由
- ビルドタスクの一覧性を担保できる
fastlane list
でタスク一覧が表示される- タスクを分類できる
fastlane platform_foo task_bar
- Androidに対応している
- Gradleタスクは簡単に実行できる
- bundle, apkのアップロードが簡単に行える
- 内部でシェルを実行できる
- どうしても移行が難しいタスクは、内部でシェルをkickすれば良い
導入後の問題点
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
が生まれているので、それを利用する- Android Studioもサジェストが出る