Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Kotlin Coroutines Flow を触ってみた話し
Tomoya Miwa
September 14, 2019
Programming
2
450
Kotlin Coroutines Flow を触ってみた話し
Tomoya Miwa
September 14, 2019
Tweet
Share
More Decks by Tomoya Miwa
See All by Tomoya Miwa
Compose の LazyColumn パフォーマンス改善で取り組んだこと
tomoya0x00
0
220
ComposeのMutableStateってどうやってLocal Unit Testすれば良いの??
tomoya0x00
0
270
意外と簡単?Navigation rail導入のお話
tomoya0x00
0
500
Android for Carsのお話し
tomoya0x00
1
720
熟成されたアプリのmulti module化(halfway)
tomoya0x00
2
560
コードカバレッジを⾒つつユニットテストを書く
tomoya0x00
0
290
multi module へ向けて
tomoya0x00
0
440
Kotlin で DSL を作り始めるまで
tomoya0x00
2
300
低レベルなKotlin
tomoya0x00
1
1.4k
Other Decks in Programming
See All in Programming
Chart実装が楽になりました。
keisukeyamagishi
0
120
What's new in Android development tools まとめ
mkeeda
0
370
設計の学び方:自分流のススメ
masuda220
PRO
10
7.2k
データ分析やAIの "運用" について考える
mmorito
0
150
オブジェクト指向で挫折する初学者へ
deepoil
0
180
設計ナイト2022 トランザクションスクリプト
shinpeim
11
2.1k
Java アプリとAWS の良い関係 - AWS でJava アプリを実行する一番簡単な方法教えます / AWS for Javarista
kanamasa
2
1.3k
Beyond Micro Frontends: Frontend Moduliths for the Enterprise @wad2022
manfredsteyer
PRO
0
130
Amazon ECSのネットワーク関連コストの話
msato
0
650
[월간 데이터리안 세미나 6월] 스스로 성장하는 분석가 커리어 이야기
datarian
0
240
プロダクトのタイプ別 GraphQL クライアントの選び方
shozawa
0
5.5k
Oracle REST Data Service: APEX Office Hours
thatjeffsmith
0
780
Featured
See All Featured
How to name files
jennybc
40
61k
The MySQL Ecosystem @ GitHub 2015
samlambert
238
11k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
151
13k
GraphQLの誤解/rethinking-graphql
sonatard
28
6.6k
Testing 201, or: Great Expectations
jmmastey
21
5.4k
Teambox: Starting and Learning
jrom
123
7.7k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
Art, The Web, and Tiny UX
lynnandtonic
280
17k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
100
5.9k
A designer walks into a library…
pauljervisheath
196
16k
How To Stay Up To Date on Web Technology
chriscoyier
780
250k
Designing with Data
zakiwarfel
91
3.9k
Transcript
Kotlin Coroutines Flowを 触ってみた話し tomoya0x00 Coroutine ハンズオン by DroidKaigi @
LINE Fukuoka #droidkaigi_roadshow
About me tomoya0x00 Twitter, GitHub, Qiita Android, Embedded system, BLE/BT,
iOS DroidKaigi staff (since DroidKaigi 2019) DeNA Co., Ltd. Automotive Business Unit.
Kotlin Coroutines Flow is 何︖
Kotlin Coroutines Flow is 何︖ https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines- core/kotlinx.coroutines. ow/ Flow —
asynchronous cold stream of elements. RxJavaみたいなもの 最近、kotlinx-coroutines-core:1.3.0でstableになった ただし、⼀部はまだexperimentalだったりpreviewだったり @ExperimentalCoroutinesApi @FlowPreview
普通の Kotlin Coroutines との違いは︖ 基本的にCoroutinesはワンショットの⾮同期処理⽤ WebAPI呼び出しとか RxJavaのSingle/Maybe/Completableと同じ⽴ち位置 Flowは何度も値を流すストリーム⽤ 位置情報とか RxJavaのObservable/Flowableと同じ⽴ち位置
⾃分が Flow を触るモチベーション
⾃分が Flow を触るモチベーション プロダクトのコードにRxJavaとCoroutinesのコードが混在 ストリームだけ、ObservableやFlowableになっている できればCoroutinesに統⼀したい そろそろStableになったし触っておこう ちょうどプロダクトで新規機能開発がある デバイス間通信(シリアル通信)の抽象化 Androidなのか・・・︖
簡単な使い⽅
簡単な使い⽅ val myFlow = flow { // flow builderの⼀つ emit(1)
emit(2) } GlobalScope.launch { myFlow.collect { value -> println("Received $value") // Received 1 // Received 2 } }
NGな使い⽅
NGな使い⽅ suspend fun hoge() = 2 val myFlow = flow
{ emit(1) // OK withContext(Dispatchers.IO) { emit(hoge()) // NG(collectする側のコンテキストの強制指定はダメ) } } GlobalScope.launch { myFlow.collect { value -> println("Received $value") } }
こうすればOK suspend fun hoge() = 2 val myFlow = flow
{ emit(1) // OK val result = withContext(Dispatchers.IO) { hoge() } emit(result) // OK } GlobalScope.launch { myFlow.collect { value -> println("Received $value") } }
いくつかTipsや困った事
いくつかTipsや困った事 Tips collectしている間、動き続けるFlow 困った事 Operetorが少ない ConnectableObservable的なモノが無い ※間違っているのもあるかもなので、気付いたら教えて下さい
Tips collectしている間、動き続けるFlow
collectしている間、動き続けるFlow シリアル通信で受信したデータをひたすらFlowで流したい シリアル通信のread()はブロッキングI/O val received: Flow<ByteArray> = flow { coroutineScope
{ // coroutineScopeでくくると、 while (isActive) { // isActiveでキャンセルされたことが検知できる val data = withContext<ByteArray>(Dispatchers.IO) { read() } emit(data) } } }
困った事 Operetorが少ない
Operetorが少ない RxJavaに⽐べると、bufferやintervalなどOperatorに不⾜を感じる coroutineなので、⼿続き的に書けば似たようなことは実現できる Operatorに関する issue は多い
val isAvailable: Flow<Boolean> = flow { coroutineScope { while (isActive)
{ val available = withContext<Boolean>(Dispatchers.IO) { var receivedAck = false // 1sec間隔で5回pingして、1回でも応答有れば利⽤可能と判定 repeat(5) { try { delay(1000L) ping() receivedAck = true } catch (e: Exception) { // Do nothing } } receivedAck } emit(available) } } }
困った事 ConnectableFlowable的なモノが無い
ConnectableFlowable的なモノが無い RxJavaにはConnectableFlowable/Observableがある 複数のSubscriberと、同じストリームを共有できる Flowには同様な仕組みがまだ無い Issueで議論されている真っ最中 Consider sharing a Flow through
a ConnectableFlow Flow.share operator 直近はBroadcastChannelを使ってどうにかしている BroadcastChannel.asFlow()で変換してFlowとして公開
感想 まだまだOperatorが少ない RxJavaでは宣⾔的に書けていたのが、⼿続き的にかかないといけ ないので思考の切替が必要 でも、逆に⾔うと⼿続き的に書けば実現できちゃうので、そこは 良い 参考になる記事も少ない sys1yagiさんの記事がめっちゃ参考になる owOn (RxJavaで⾔うsubscribeOn)
ですらexperimental API変更はありえる
結論
まだ⼿を出すにはちょっと早いかも︖
でも、ぜひ使ってフィードバックしてい きましょう︕
ありがとうございました