Flow - Ki-Kobayashi/Android-Wiki GitHub Wiki

🟩 公式

https://developer.android.com/kotlin/flow?hl=ja

🟡

.

🟩 Producer(生産側) より Consumer(消費/受け取り側)が遅い時の問題

◆問題の条件

  • はやい:Producer(生産側)
  • おそい:Consumer(消費/受け取り側)

 

🟡 何が問題か

上記の場合、下記の問題が発生する

  • 「ブロッキングエラー」
  • 「メモリーエラー」

.

🟩 combine 関数

combine は、KotlinのFlow APIの一部であり、複数の非同期データソース(Flow)を組み合わせて新しい Flow を生成するための関数。
具体的には、combine は複数の Flow を監視し、どれか一つの Flow が新しい値を放出すると、指定したロジック(ラムダ式)が実行され、その結果として新しい Flow が生成される
.
🟡基本系

combine(
    flow1,  // 最初のFlow
    flow2,  // 2番目のFlow
    // ...
) { value1, value2, ... ->
    // value1, value2, ... は各Flowの最新の値を表す
    // これらの値を組み合わせて新しい値を生成するロジックを記述
}

.
🟡実例
https://github.com/android/nowinandroid/blob/main/core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCase.kt

// "invoke" オペレーターをオーバーロードした関数
operator fun invoke(sortBy: TopicSortField = NONE): Flow<List<FollowableTopic>> = combine(
    // 2つの非同期データソース(ユーザーデータとトピックのリスト)を組み合わせる
    userDataRepository.userData,
    topicsRepository.getTopics(),
) { userData, topics ->
    // トピックをフォローできる形式に変換する
    val followedTopics = topics
        .map { topic ->
            FollowableTopic(
                topic = topic,
                // トピックがユーザーによってフォローされているかどうかを示す
                isFollowed = topic.id in userData.followedTopics,
            )
        }

    // ソートの基準に応じてトピックをソートする
    when (sortBy) {
        // 名前順でソートする場合
        NAME -> followedTopics.sortedBy { it.topic.name }
        // それ以外の場合は元の順序のまま
        else -> followedTopics
    }
}

🟡

.

🟩 サーバーサイドAPIからFlowで取得するときに考慮すること

  • 🚨そもそも、サーバーサイドでの変更通知メカニズムがない場合、クライアント側でFlowを使って自動的な変更通知を行うのは難しい。
  • 代わりに、上記で述べたような手動や定期的な更新の仕組みを検討すること。
  • ただし、これらの方法もコストやパフォーマンスの観点から検討が必要

.

🟡一般的には【Flow】は以下のケースで使用

sealed class Future<out T> {
    // APIコールが実行中である
    object Proceeding : Future<Nothing>()

    // APIコールが成功した
    data class Success<out T>(val value: T) : Future<T>()

    // APIコールが失敗した
    data class Error(val error: Throwable) : Future<Nothing>()
}

.

🟡用語理解

💎ポーリング(Polling):

  • データに変更があるかどうかを確認するために、定期的にサーバーにリクエストを送る手法
  • クライアントがサーバーに対してアクティブに問い合わせを行い、新しい情報があるかどうかを確認
  • 🚨ポーリングはリソースの浪費や遅延が発生する可能性があるため、避けた方がいいことも

.

💎定期的なデータ取得:

  • データに変更があるかどうかに関わらず、定期的にサーバーに対してデータを取得する手法
  • クライアントが定期的にデータを取得しに行く形で、変更があるかどうかは取得したデータを確認して判断
  • 🚨サーバーに対する負荷が高まる可能性がある

.

💎手動リフレッシュ:

  • ユーザーに手動でデータをリフレッシュするオプションを提供する方法
  • ユーザーが必要に応じてデータを更新できる

🟡サーバーサイドで変更通知メカニズムを作成するには「WebSocket」

Roomは、そうした機能をあらかじめ実装されているため、Flowの使用ができる https://copyprogramming.com/howto/kotlin-flow-and-websockets-with-clean-architecture-on-android

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

⚠️ **GitHub.com Fallback** ⚠️