Wersja interfejsów API Home w Kotlinie korzysta z przepływów, czyli funkcji języka Kotlin, która zapewnia zaawansowane możliwości obsługi asynchronicznych strumieni danych, w tym przekształcania, filtrowania, mapowania, konwertowania na kolekcje i z nich itp.
Coroutines są ściśle powiązane z przepływami i stanowią elegancką abstrakcję do pisania kodu asynchronicznego. Dzięki nim deweloper nie musi już jawnie pisać procedur wywołania. Przepływy współpracują z korowinatami, umożliwiając asynchroniczne pobieranie danych z nich bez konieczności czekania na zakończenie funkcji lub wątku.
Dane są pobierane z przepływu przez konsumenta w ramach procesu o nazwie zbieranie.
Przepływy w Kotlinie mają funkcję collect()
, która może być używana do tego celu. To, co dzieje się w procesie podczas zbierania danych, zależy od jego typu.
Domyślnie procesy Kotlina (Flow<T>
) są zimne, co oznacza, że kod kreatora procesów generuje dane tylko wtedy, gdy wywoływana jest funkcja collect()
. Natomiast gorący przepływ danych natychmiast generuje dane, buforując je w pamięci jako kolejkę, z której dane są pobierane. Ponieważ przechowuje dane w pamięci, gorący przepływ jest uważany za stanowy.
Za pomocą operatora shareIn
możesz przekształcić ścieżki z zimnych w ciepłe (zobacz Zmienianie zimnych ścieżek w ciepłe za pomocą operatora shareIn
). Możesz też użyć operatora SharedFlow
lub StateFlow
, aby przekształcić zimną ścieżkę w ciepłą.
Jak przykładowa aplikacja korzysta z przepływów
Przykładowa aplikacja korzysta z modeli widoku w Jetpack Compose połączonych z przepływami w interfejsach API Home. Wiele elementów interfejsu w próbnej aplikacji jest zależnych od stanu, ale można z nimi wchodzić w interakcje. Przykładowa aplikacja łączy stany urządzeń z „optymistycznym” stanem w interfejsie, aby zapewnić użytkownikom wrażenia w czasie rzeczywistym. Termin „optymistyczny” oznacza, że aplikacja zakłada, że dane działanie zakończyło się powodzeniem, i natychmiast aktualizuje interfejs, aby odzwierciedlić oczekiwany wynik, bez oczekiwania na potwierdzenie. Jeśli okaże się, że działanie się nie powiodło, interfejs użytkownika zostanie zaktualizowany, aby odzwierciedlić rzeczywisty stan.
W przykładowej aplikacji przepływy są tworzone dla każdej warstwy modelu widoku (struktury, pomieszczenia, urządzenia). Na przykład w przypadku struktur z tym wywołaniem w GlobalViewModel.kt
:
fun getStructuresState(): StateFlow<List<StructureModel>?> =
homeClient
.structures()
.map { structures -> structures.map { StructureModel(it.name, it) }.sortedBy { it.name } }
.handleErrors()
.flowOn(Dispatchers.IO)
.stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), null)
emitAll()
zbiera wszystkie wartości z danego przepływu i wysyła je do odbiornika. stateIn()
udostępnia ostatnio wyemitowaną wartość z pojedynczej instancji przepływu w górę z wieloma subskrybentami w dół. Więcej informacji znajdziesz w dokumentacji kotlinx.coroutines.flow
.
Jetpack Compose
Aby przechowywać obiekty przepływu w pamięci lokalnej i zapobiegać ich zakończeniu, użyj interfejsu API Kotlina remember
.
Jeśli w Jetpack Compose korzystasz z elementu collectAsStateWithLifecycle()
, Jetpack automatycznie zarządza subskrypcjami i rezygnacją z nich w zależności od tego, czy interfejs użytkownika aplikacji, który pokazuje ten stan, znajduje się na pierwszym planie, czy nie.
Wystarczy wywołać go w przykładowej aplikacji. Korzystając z funkcji getStructuresState()
, która została wcześniej pokazana:
val structuresList by
remember(globalViewModel) { globalViewModel.getStructuresState() }.collectAsStateWithLifecycle()
Teraz, gdy zmieni się jakikolwiek stan struktury (np. name
), funkcja składana, która z niego korzysta, automatycznie odzwierciedli tę zmianę.
W przykładowej aplikacji jest to funkcja HomeActivityContent()
.
Zasoby
Więcej informacji o Kotlin, przepływach, współbieżnych wątkach i Jetpack Compose znajdziesz w tych materiałach:
- Tworzenie aplikacji na Androida w Kotlinie
- Nauka języka Kotlin na potrzeby Androida
- Kotlin coroutines na Androidzie. Te laboratoria programistyczne mogą być przydatne:
- Kotlin Flows na Androidzie, a w szczególności StateFlow.
- Stan i Jetpack Compose, a w szczególności funkcja
collectAsStateWithLifecycle()
. Ta funkcja automatycznie zarządza subskrypcją i anulowaniem subskrypcji przepływów na podstawie tego, czy interfejs użytkownika pokazujący ten stan jest rzeczywiście na pierwszym planie. - Jeśli pracujesz z interfejsem Automation API, przeczytaj artykuł Kotlin: bezpieczne konstruktory typu, aby lepiej zrozumieć, jak działa Automation DSL.