Flow.
Context
Author:Semen Naduiev
Introduction to Flow
Flow is a cold and asynchronous data stream in Kotlin that emits multiple values over time.
It is part of Kotlin Coroutines and is designed to replace LiveData for reactive programming in
Android.
Flow supports suspension, backpressure handling, and transformations like map, filter, and
collect.
Why Use Flow?
✅ Reactive Data Streams – Flow continuously emits values over time.
✅ Asynchronous – Works with coroutines to manage background tasks efficiently.
✅ Better than LiveData – Supports operators, error handling, and cancellation.
✅ Cold Stream – Data is only produced when collected, avoiding unnecessary computations.
Basic Flow Example
flow {} – Creates a Flow that emits values.
emit(value) – Sends a value to the
collector.
collect {} – Receives and processes
values one by one.
Flow Operators
Flow provides powerful operators for transformation and filtering:
simpleFlow()
.map { it * 2 } // Transform values
.filter { it % 2 == 0 } // Keep only even values
.collect { println(it) } // Collect results
map {} – Transforms each emitted value.
filter {} – Filters values based on conditions.
collect {} – Collects and processes values.
StateFlow & SharedFlow
StateFlow – Emits the latest state
and is hot (always active).
SharedFlow – Broadcasts values to
multiple collectors, like an event
bus.
ViewModel with Flow Example
✅ stateIn() converts a Flow into a
StateFlow, making it usable in Compose.
✅ viewModelScope ensures the Flow
lives as long as the ViewModel.
✅ SharingStarted.Lazily starts collecting
data only when observed.
Collecting Flow in Compose
How it Works:
🔹 collectAsState() automatically
re-renders the UI when Flow emits new data.
🔹 No need for LiveData or manual
observers.
🔹 Fully reactive and efficient UI updates!
Handling UI State with Flow
What is the Repository Pattern?
● The Repository Pattern is a structural pattern that separates the data access logic from
the business logic.
● It acts as an intermediary between the data source (API, database) and the rest of the app.
● Helps in code reusability, separation of concerns, and testability.
Key Benefits:
✅ Encapsulates data access logic.
✅ Supports multiple data sources (API, Database, Cache).
✅ Improves maintainability and testability.
Flow in Repository Pattern (MVVM Example)
What is Android Context?
Context in Android provides access to application-specific resources and environment
information.
It allows interaction with system services, databases, preferences, and UI elements.
Almost everything in Android (starting activities, inflating layouts, accessing resources) requires
a valid Context.
Types of Context in Android
Application Context vs Activity Context
Context in Compose
Mostly, you access resources using stringResourse(R.string.your_string) of
getDimentions(R.dimen.your_dimen). It use activity context under the hood. To access context
manually you can use LocalContext.current.
What Are Side Effects in Jetpack Compose?
Side effects are operations that affect the app's state but happen outside the composable function's
scope.
Examples:
● Fetching data from a network.
● Writing to a database.
● Updating shared preferences.
● Logging or analytics.
Why manage them? Because Jetpack Compose recomposes UI frequently, leading to unintended
repeated execution.
Side Effect APIs in Jetpack Compose
LaunchedEffect – Running Suspend Functions
Used for one-time or
key-based effects in a
coroutine scope.
Automatically cancels and
restarts when key changes.
DisposableEffect – Cleanup Needed
Used when you need to set up
and clean up resources, like
listeners or sensors.
SideEffect – Lightweight UI Updates
What is Gradle?
Gradle is a build automation tool used for compiling, testing, packaging, and deploying Android
apps.
It is declarative (via build.gradle.kts) and supports incremental builds for faster performance.
It manages dependencies, plugins, and tasks to simplify app development.
Gradle in Android Projects
Gradle Dependencies
Gradle manages libraries and tools via dependencies.
There are three common types:
Gradle Build Variants & Flavors
Gradle allows creating multiple app versions (e.g., free vs. premium) using build variants.
Defined inside the android block.
What is an Intent?
Intent is a messaging object used to communicate between components in Android.
Can be used to start activities, services, or send broadcasts.
There are two types of intents:
● Explicit Intent – Targets a specific component.
● Implicit Intent – Allows other apps to handle the request.
Explicit Intent
Used when starting a specific activity or service within the same app.
Example: Navigating to another Activity
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("message", "Hello from MainActivity")
startActivity(intent)
Retrieving data in SecondActivity:
val message = intent.getStringExtra("message")
textView.text = message
Implicit Intent
Used when the app doesn’t specify the target component.
Lets other apps handle the request (e.g., opening a website, sending an email).
Passing Data with Intents
You can attach extra data to an Intent using putExtra().
Different data types supported:
Starting an Activity for Result
Sometimes you need to get a result from another activity.
Use registerForActivityResult() instead of the deprecated startActivityForResult().