376 Followers
·
Follow

Coroutines 1.4.0-M1SharedFlow が入ったので、使い方を紹介します。

Image for post
Image for post
Photo by Fidel Fernando on Unsplash

SharedFlow?

SharedFlow は名前の通り Flow ですが、普通の Flow は Cold Stream に対して、こちらは Hot Stream になります。Flow と異なり Complete することはないのです。

また、キャッシュとバッファリングに対応することができます。

SharedFlow で発行された値は collect (サブスクライブ)してる箇所すべてに通知されるます。

ユースケース

以下のIssueのdescriptionを見てみてください。

同期的なイベントリスナーとか、イベントをキャッシュとかリプレイするとか、みたいな感じですかね。

個人的に、Androidでは LiveData を使ってイベント通知(SingleLiveEvent)などやってたと思いますが、それの代わりになりそうだなぁって思っています。
(これは後日まとめたいと思います)

簡単な使い方

Androidやってる方は LiveData と同じような使い方に見えると思いますが、だいたいそんな感じです。

MutableSharedFlow という値を発行可能なものを用意して SharedFlow でそれを外部に公開する。公開された SharedFlowcollect して値を受信できるようにする感じです。

値を発行するときは emit という suspend 関数を呼び出します。suspend関数なので注意してください。

キャッシュ と バッファリング

まずは MutableSharedFlow の生成するときの引数を見てみます。デフォルト引数は次のような感じになっています。

private val _event = MutableSharedFlow<Event>(
replay = 0,
extraBufferCapacity = 0,
onBufferOverflow = BufferOverflow.SUSPEND

)

これらの引数を使って、キャッシュとバッファリングの制御を行います。

キャッシュ

ドキュメントでは Replay cache と呼んでるみたいです

最初の replay 引数は発行された値を保存するキャッシュの件数になります。デフォルトは 0


Kotlin 1.4で改善されたSAM変換についてまとめます

Kotlin interfaceのSAM変換

これまでKotlinのinterfaceはSAM変換できず、以下のように object キーワードを明示的に使う必要がありました。
(Java interfaceの場合はこれまでもSAM変換できていました)

Kotlin 1.4ではKotlin interfaceでもSAM変換が可能になりました。ただし、そのままで使えず、interfaceに fun 修飾子を付ける必要があります。

Java interfaceの異なる引数のSAM変換

例えば、以下のようなJavaコードがあったとします。引数で2つのSAM変換可能なinterfaceを受け取ります。

これをKotlinから使うときはSAM変換できるのは、両方ともラムダ式にした場合のみでした。片方がオブジェクトになってる場合は片方をラムダにはできませんでした。

Kotlin 1.4からは片方がオブジェクトとラムダを混ぜることが可能になりました。

Android開発での影響

これの影響として、Android開発で使われるktxの拡張関数が一部不要になったりします。

例えば、LiveDataでobserveするときにktxを使うことで記述を楽にすることができました。

liveData.observe(this) { }

これがKotlin 1.4からはktxがなくても可能になります。

これに伴い、こちらの拡張関数はDeprecatedになる予定です。

他にもktx等の拡張関数が不要になるものがあるかもです。

KotlinでのJava SAM変換

これまではJava SAM変換を適用して、以下のような書き方ができませんでした。

Kotlin 1.4からはSAM変換を適用できるようになりました。

参考


Jetpack Composeでレイアウトを組むための基本的なまとめです

Image for post
Image for post
Photo by La-Rel Easter on Unsplash

Jetpack Composeでは、これまでのViewシステムとは違うためレイアウトを組むのに手こずったので、基本的なことを簡単にまとめました。

ConstraintLayoutについては今回は触れてません。

Composeのバージョンはalpha02を使っています。

レイアウトComposable

レイアウトを組むのに使用できるComposableです。これらを組み合わせてレイアウト組んでいくことになります。

Box

Box(
modifier = Modifier.preferredSize(120.dp, 60.dp),
backgroundColor = Color.Yellow,
gravity = ContentGravity.Center
) {
Text(text = "Sample")
}
Image for post
Image for post

サイズを指定して描画するものになります。もしサイズが親より大きいものが指定されたときは、それを超えることはないです。

gravity で中にある要素の配置を指定することができます。
( Modifier.gravity とは異なる)

単純にサイズを指定して描画したいときに使えるかと思います。

Stack

Stack {
Box(
modifier = Modifier.preferredSize(120.dp),
backgroundColor = Color.Yellow
)
Box(
modifier = Modifier.preferredSize(80.dp),
backgroundColor = Color.Blue
)
Box(
modifier = Modifier.preferredSize(40.dp),
backgroundColor = Color.Red
)
}
Image for post
Image for post

これは上に要素を重ねていくレイアウトになります。FrameLayout みたない感じですね。

Column

Column {
Box(
modifier = Modifier.preferredSize(120.dp, …

About

Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store