Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Mori Atsushi 2019年度 新卒⼊社 株式会社CyberZ OPENREC.tv CyberZ CTO室 メンバー 次世代マネジメント室 メンバー 未踏スーパークリエータ @at_sushi_at @Mori-Atsushi

Slide 3

Slide 3 text

https://note.com/cyberz_cto/n/n f d c

Slide 4

Slide 4 text

https://zenn.dev/at_sushi_at/books/edf adfc

Slide 5

Slide 5 text

• Kotlinの公式ライブラリ • ⾮同期処理を強⼒に⽀援、まるで同期処理のように書ける Kotlin Coroutines Kotlin Coroutines Features/Promises/Rx

Slide 6

Slide 6 text

• Googleも推奨するソリューション • AndroidのLifecycleに沿ったキャンセルを実現可能 • 周辺ライブラリもCoroutinesをサポート Retrofit, grpc-kotlin, Room, DataStore, Paging , Store , Jetpack Compose Android 🤝 Kotlin Coroutines • Lifecycle, Dispatchers, CoroutineContext, エラーハンドリング, キャンセル処理, バッファ 注意する点は多い

Slide 7

Slide 7 text

🚀 今回のゴール 既にKotlin Coroutinesを使って Androidアプリを開発している⽅に向け、 キャンセルについてより詳しく知ってもらう。 • より安全に • より効率的に • より保守しやすいよう

Slide 8

Slide 8 text

໨࣍ Contents ໨࣍ Contents ໨࣍ Contents ໨࣍ Contents ໨࣍ Contents . Kotlin Coroutinesのキャンセルを扱う 2. 正しくキャンセルする 3. 正しくキャンセルさせない

Slide 9

Slide 9 text

. Kotlin Coroutinesのキャンセルを扱う

Slide 10

Slide 10 text

• モバイルデバイスという限られたリソースで、 正しく処理を中断することは重要 • 例えば フォアグラウンドのときのみUIを更新する 現在の画⾯を閉じたらリクエスト中のAPIを終了する キャンセル https://developer.android.com/topic/libraries/architecture/viewmodel

Slide 11

Slide 11 text

• CoroutinesScopeやJobは キャンセル可能 • delay等のsuspend functionが CancellationExceptionを throwしている Coroutinesのキャンセルの仕組み CancellationExceptionをthrow キャンセル時のハンドリング キャンセル時もそうでないときも 実⾏される

Slide 12

Slide 12 text

• LifecycleOwner.lifecycleScope Lifecycleが破棄されたとき(onDestory)に⾃動的にキャンセルされる • ViewModel.viewModelScope ViewModelの消去時 (onCleared) に⾃動的にキャンセルされる AndroidとCoroutinesのキャンセル

Slide 13

Slide 13 text

2. 正しくキャンセルする

Slide 14

Slide 14 text

問題:以下のコードはどのように実⾏されるか? 1,000,000までインクリメント 500,000のタイミングでキャンセル

Slide 15

Slide 15 text

正解:1,000,000までインクリメントされる 1,000,000までインクリメント 500,000のタイミングでキャンセル 実⾏結果

Slide 16

Slide 16 text

なぜ? • Coroutinesは常にキャンセルされたかどうかを 知っているわけではない • delay等の⼀部のsuspend functionのみ キャンセルされたかどうか確認している • キャンセルされているか確認するタイミングが なければ、最後まで実⾏される

Slide 17

Slide 17 text

• ensureActiveでキャンセルされてないか確認する 注意点①:キャンセルに対して協⼒的である必要がある 500,000のタイミングでキャンセル 1,000,000までインクリメント 実⾏結果 キャンセルされていれば CancellationExceptionをthrow

Slide 18

Slide 18 text

どのようなコードで考慮すべきか? • 通常の処理で問題になることは少ない あちこちにキャンセルチェックがあると、 本質と異なる情報が混じり可読性が落ちる • 例えば: バックグランドスレッドで重たいアルゴリズムを動作させている場合 ディスクから複数のファイルを読み込む場合

Slide 19

Slide 19 text

注意点②:suspendCancellableCoroutineを使う • callback処理をsuspend function に変更するsuspendCoroutineは キャンセルに対応していない • 可能な限り suspendCancellableCoroutine を使う キャンセル時の処理

Slide 20

Slide 20 text

注意点③: CancellationExceptionをcatchしない • キャンセル時にthrowされる CancellationExceptionも catchしてしまうと キャンセルされない キャンセルされてもリトライしてしまう キャンセル時に CancellationExceptionをthrowする エラーになった際にretryする関数

Slide 21

Slide 21 text

解決策 • 特定のエラーだけ try-catchする • CancellationExceptionを 再throwする エラーになった際にretryする関数 キャンセル時に CancellationExceptionをthrowする キャンセルを呼び出し元に 伝播させる

Slide 22

Slide 22 text

3. 正しくキャンセルさせない

Slide 23

Slide 23 text

• 画⾯を閉じた際等にキャンセルさせたくない 処理も存在する • 例えば 購⼊完了後のレシート処理 ログ送信処理 キャンセルさせたくない処理 ViewModel破棄後も続⾏させたい

Slide 24

Slide 24 text

良くない⽅法:GlobalScopeを使う • アプリケーション期間のCoroutineScope (@DelicateCoroutinesApi) • contextが不明瞭 Dispatcherは? JobかSupervisorJobか? エラーハンドリングは? • テストでも キャンセルができない ViewModel破棄後も続⾏される GlobalScopeでlaunch

Slide 25

Slide 25 text

注意が必要:NonCancellableを利⽤する • キャンセルできないJob • 記述はシンプルでわかりやすい • 個別のキャンセルも できなくなり、 制御が不可能 • テストでも キャンセルができない • クリーンアップ等では便利 ViewModel破棄後も続⾏される withContextで指定

Slide 26

Slide 26 text

個別のキャンセルも出来ない • withContext(NonCancellable) はいかなる⽅法でも キャンセルできない • 将来的に予期せぬ不具合を 引き起こす可能性がある jobをcancelしてもapi.purchaseは続⾏される

Slide 27

Slide 27 text

おすすめ:アプリケーション範囲のCoroutineScopeをDIする • CoroutineScopeを⾃作 • テストで制御可能 • 共通のcontextが利⽤可能 • 個別の制御も可能 ViewModel破棄後も続⾏される appScopeでlaunch エラーハンドラー JobやDispatcher appScopeを定義

Slide 28

Slide 28 text

まとめ • キャンセルを意識することでリソースを効率的に扱うことが出来る • 正しくキャンセルさせる キャンセルに対して協⼒的である必要がある suspendCancellableCoroutineを使う CancellationExceptionをcatchしない • 正しくキャンセルさせない アプリケーション範囲のCoroutineScopeをDIする

Slide 29

Slide 29 text

参考⽂献 • Mori Atsushi, 詳解 Kotlin Coroutines [ ], https://zenn.dev/at_sushi_at/books/edf adfc • Kotlin coroutines on Android | Android Developers, https://developer.android.com/kotlin/ coroutines • Best practices for coroutines in Android | Android Developers, https://developer.android.com/ kotlin/coroutines/coroutines-best-practices • Cancellation in coroutines. Cancellation and Exceptions in | by Florina Muntenescu | Android Developers | Medium, https://medium.com/androiddevelopers/cancellation-in-coroutines- aa b • Coroutines & Patterns for work that shouldn’t be cancelled | by Manuel Vivo | Android Developers | Medium, https://medium.com/androiddevelopers/coroutines-patterns-for-work-that-shouldnt-be- cancelled-e c f ad

Slide 30

Slide 30 text

No content