非同期処理でCoroutine(コルーチン)を使ってみる (Android Kotlin)

/


いよいよ非同期処理もコルーチンへ移行しようと思っているので理解できている範囲で使い方をまとめておく。



ライブラリのインストール



Androidアプリでコルーチンを使えるようにするためにGradleでインストールする。

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'



ScopedAppActivityクラスの作成



公式ドキュメントにあるようにAppCompatActivityを継承したScopedAppActivityクラスを作る。
https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md



次のようにしてコルーチンを使うアクティビティでScopedAppActivityを継承するようにする。


これにより、onDestroyでコルーチンのJobキャンセルし忘れがなくなり、記述も簡潔に書けるようになる。


launchを使う




新しいコルーチンを起動するためにはこのようにlaunchを使う。引数を指定していないのでブロック内はメインスレッドとなる。
またdelayはコルーチンを中断する関数で次のようにsuspendで定義されている。




コルーチンで非同期処理を書く




asyncを使って非同期処理を書く。awaitを使うことで実行結果を待つことが出来る。UIにアクセスする場合はwithContext(Dispatchers.Main) ブロック内に書くこと。ただし上記の場合はwithContext(Dispatchers.Main)の記述が無くても問題なく動く。asyncブロック内の最後の行が戻り値となる。returnをつけてはいけないことになっている。


suspend関数



コルーチンのasyncを使った非同期処理の部分を関数に移したい場合はsuspendを使う。




asyncを使わずwithContextを使って書く。



先程のプログラムは次のようにも書ける。asyncを使った場合との厳密的な違いはわからない。suspendとwithContextを使ったこちらのほうが個人的には分かりやすいと思っている。




View.onClickを拡張する





のようにlaunchの記述がいちいち面倒な場合はサンプルドキュメントのようにView.onClickを拡張してしまう。



するとこのようにシンプルに書けるようになる。




ここまでのMainActivityのまとめ



ここまでのサンプルソースを載せておこう。




suspend内のコルーチンのキャンセル



ベストプラクティスかどうかはわからないが、CoroutineScopeをメンバ変数に保持してcancelTaskを呼び出することでキャンセルさせることが出来る。



キャンセルされたら例外が投げられるのでそれをフックする。ただし非同期処理でOkHttpの処理を書いてみたがOkHttpはキャンセルされなかった。その場合はOkHttpのCallをキャンセルさせたほうが良さそうだ。




参考



https://kotlinlang.org/docs/reference/coroutines/basics.html
https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md




関連記事


非同期 & ネットワーク処理
* はじめてRetrofitを使ってみる (Android Kotlin)
* 非同期処理でCoroutine(コルーチン)を使ってみる (Android Kotlin)
* OkHttpでHTTP通信 (Android Kotlin)
* スレッド処理 (Android Kotlin)

View & レイアウト
* リサイクラービューを使ってリスト表示 (Android Kotlin)
* 角丸表現 (Android Kotlin)
* onSaveInstanceStateで画面回転時の状態の保存と復元 (Android Kotlin)
* ListViewを簡単なモデルで理解しよう (Android Kotlin)
* バネアニメーション (Android Kotlin)
* startActivityForResultを使ってみる (Android Kotlin)
* ActivityとFragmentの連携を理解する (Android Kotlin)
* DataBinding機能を使ってみる (Android Kotlin)
* タッチイベントのフック (Android Kotlin)
* DialogFragmentを使ったダイアログの表示 (Android Kotlin)

サウンド
* これってSoundPoolのバグ?(Android Kotlin)
* SoundPoolを使ってゲームの効果音を再生する (Android Kotlin)

データ & オブジェクト
* Kotlinでオブジェクト(object)の動作確認
*
データクラスとタプル (Android Kotlin)
* Null安全、ぬるぽバイバイ (Android Kotlin)