State Flow und Shared Flow in Kotlin

Apr 20 2023
State Flow Schritt 1: Erstellen Sie eine Modellklasse. Im Gegensatz zu einem normalen Flow, der kalt ist und erst dann Werte ausgibt, wenn ein Collector angefügt wird, ist ein SharedFlow heiß und beginnt sofort mit der Ausgabe von Werten an alle aktuellen und zukünftigen Collectors, sobald sie angefügt sind.
Foto von Marc Reichelt auf Unsplash

Zustandsfluss

  • StateFlowist ein vom Statushalter beobachtbarer Fluss, der die aktuellen und neuen Statusaktualisierungen an seine Kollektoren ausgibt.
  • Ein SharedFlow, der einen schreibgeschützten Zustand mit einem einzelnen aktualisierbaren Datenwert darstellt, der Aktualisierungen des Werts an seine Kollektoren ausgibt.
  • State Flow ist als effizientere und vereinfachte Version der vorhandenen Flow-Bibliothek von Kotlin konzipiert, mit dem Hauptunterschied, dass es einen einzelnen Wert darstellt, der im Laufe der Zeit aktualisiert werden kann, während Flow eine Folge von Werten darstellt.
  • State flow verwendet eine ähnliche Syntax wie Flow, aber anstatt einen Stream von Werten auszugeben, stellt er einen einzelnen Wert bereit, der mithilfe der valueEigenschaft aktualisiert werden kann. Änderungen an diesem Wert werden automatisch an alle Beobachter des Zustandsflusses weitergegeben.
  • Ein Zustandsfluss ist ein heißer Fluss, da seine aktive Instanz unabhängig vom Vorhandensein von Kollektoren existiert.
  • A StateFlowist immer aktiv und im Speicher, und es wird nur dann für die Garbage Collection geeignet, wenn es keine anderen Verweise darauf von einem Garbage-Collection-Stamm gibt.
  • Ein änderbarer Zustandsfluss wird mithilfe der MutableStateFlow(value)Konstruktorfunktion mit dem Anfangswert erstellt.
  • Alle Methoden des Zustandsflusses sind Thread-sicher und können sicher von gleichzeitigen Coroutinen ohne externe Synchronisation aufgerufen werden.

Schritt 1: Modellklasse erstellen

data class User(val id: Int, val name: String, val email: String)

class UserRepository {
    suspend fun getUserById(userId: Int): User {
        // make API call to fetch user data
        val response = // make API call here
        return response.toUser() // convert API response to User object
    }
}

class UserViewModel(private val repository: UserRepository) : ViewModel() {
    private val _user = MutableStateFlow<User?>(null)
    val user: StateFlow<User?> = _user

    fun getUserById(userId: Int) = viewModelScope.launch {
        _user.value = repository.getUserById(userId)
    }
}

class UserFragment : Fragment() {
    private val viewModel: UserViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val userId = arguments?.getInt("userId") ?: throw IllegalArgumentException("userId is required")

        viewModel.getUserById(userId)

        viewModel.user.onEach { user ->
            userTextView.text = user?.name ?: "Loading..."
            emailTextView.text = user?.email ?: ""
        }.launchIn(viewLifecycleOwner.lifecycleScope)
    }
}

Geteilter Fluss

In Kotlin SharedFlowist a eine Art Flow, der es mehreren Sammlern ermöglicht, emittierte Werte von einem einzigen Produzenten zu empfangen. Im Gegensatz zu einer normalen Flow, die kalt ist und erst dann Werte ausgibt, wenn ein Kollektor angeschlossen ist, SharedFlowist eine heiß und beginnt sofort mit der Ausgabe von Werten an alle aktuellen und zukünftigen Kollektoren, sobald sie angeschlossen sind.

A SharedFlowkann in Situationen nützlich sein, in denen Sie einen Datenstrom zwischen mehreren Komponenten Ihrer Anwendung freigeben müssen, z. B. wenn Sie mehrere Teile Ihrer Benutzeroberfläche über eine Änderung einiger Daten benachrichtigen möchten.

class MainViewModel : ViewModel() {

    private val _items = MutableSharedFlow<List<Item>>()
    val items: SharedFlow<List<Item>> = _items

    fun startFetchingItems() {
        viewModelScope.launch {
            while (true) {
                val newItems = fetchItemsFromApi()
                _items.emit(newItems)
                delay(5000)
            }
        }
    }

    private suspend fun fetchItemsFromApi(): List<Item> {
        // code to fetch items from API
    }
}

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: ItemAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recyclerView)
        adapter = ItemAdapter(emptyList())

        recyclerView.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)
            setHasFixedSize(true)
            this.adapter = [email protected]
        }

        val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

        lifecycleScope.launchWhenStarted {
            viewModel.items.collectLatest { items ->
                adapter.updateItems(items)
            }
        }

        viewModel.startFetchingItems()
    }
}

collectLatestist eine Funktion höherer Ordnung in der FlowAPI von Kotlin, die es Ihnen ermöglicht, ausgegebene Werte von a zu sammeln Flowund eine Transformation nur für den neuesten Wert durchzuführen. Es ähnelt collect, das zum Sammeln aller ausgegebenen Werte verwendet wird, collectLatestverarbeitet jedoch nur den zuletzt ausgegebenen Wert und ignoriert alle vorherigen Werte, die noch nicht verarbeitet wurden.

Diff zwischen State-Flow und Shared-Flow

Hier sind einige der wichtigsten Unterschiede zwischen SharedFlowund StateFlowin Kotlin:

  1. Veränderlich vs. unveränderlich: StateFlowist ein unveränderlicher Datenbehälter, der einen einzelnen Wert darstellt, der beobachtet werden kann, während SharedFlowes sich um einen veränderlichen Datenbehälter handelt, der mehrere Werte ausgeben kann.
  2. Fehlerbehandlung: StateFlowhat keine eingebaute Fehlerbehandlung, SharedFlowunterstützt aber die tryEmitFunktion, die eine sichere Ausgabe von Werten und die Weitergabe von Fehlern an nachgeschaltete Kollektoren ermöglicht.
  3. Backpressure Handling: StateFlowVerwendet eine Backpressure-Strategie namens „Conflation“, die automatisch Zwischenwerte löscht, die zu schnell ausgegeben werden, als dass der Collector damit Schritt halten könnte. SharedFlowermöglicht eine feinkörnigere Kontrolle über die Behandlung des Gegendrucks durch seine Parameter bufferund onBufferOverflow.
  4. Sendeverhalten: SharedFlowist für das Senden von Werten an mehrere Sammler ausgelegt, während StateFlowes für die Beobachtung eines einzelnen Werts ausgelegt ist.
  5. Anwendungsfälle: StateFlowWird häufig verwendet, um eine einzige Quelle der Wahrheit in einer Anwendung darzustellen, z. B. den aktuellen Zustand einer UI-Komponente oder die Daten in einer Datenbank. SharedFlowwird häufig für Situationen verwendet, in denen mehrere Teile einer Anwendung dieselbe Datenquelle überwachen müssen, z. B. in einer Messaging-App, in der mehrere Benutzer denselben Chatroom beobachten müssen.

Abschluss

Zusammenfassend bieten Kotlin SharedFlowund StateFlowEntwickler leistungsstarke Tools zur Implementierung reaktiver Programmiermuster in Android-Anwendungen.

StateFlowstellt einen einzigen unveränderlichen Wert dar und ist ideal für die Darstellung einer Single Source of Truth in Ihrer App.

SharedFlowist änderbar und kann mehrere Werte ausgeben, wodurch es besser für die Übertragung von Werten an mehrere Sammler geeignet ist.

Jede hat ihre eigenen Stärken und Schwächen, und die Wahl der zu verwendenden hängt von den spezifischen Anforderungen Ihrer App ab.

Ich hoffe, dieser Artikel war hilfreich für Sie.

Wenn Sie Feedback oder Fragen haben, schreiben Sie mir bitte an [email protected]. Ihr Klatschen wird wirklich geschätzt, um anderen zu helfen, diesen Artikel zu finden .

Level-Up-Codierung

Danke, dass Sie ein Teil unserer Community sind! Bevor du gehst:

  • Klatsche für die Geschichte und folge dem Autor
  • Sehen Sie sich weitere Inhalte in der Level Up Coding-Publikation an
  • Kostenloser Kurs für Programmierinterviews ⇒ Kurs anzeigen
  • Folge uns: Twitter | LinkedIn | Newsletter