Room with Flow helps your app watch database changes and update the screen automatically. It makes your app feel fast and fresh without manual refresh.
Room with Flow for reactive data in Android Kotlin
import kotlinx.coroutines.flow.Flow @Dao interface MyDao { @Query("SELECT * FROM my_table") fun getAllItems(): Flow<List<MyEntity>> }
The function returns a Flow that emits data updates automatically.
Use Flow with Kotlin coroutines for reactive streams of data.
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getUsers(): Flow<List<User>>
}@Dao
interface TaskDao {
@Query("SELECT * FROM tasks WHERE done = 0")
fun getPendingTasks(): Flow<List<Task>>
}This example shows a Room entity Note and a DAO returning a Flow of all notes. The ViewModel collects this flow and updates a state flow to keep UI reactive.
import androidx.room.* import kotlinx.coroutines.flow.Flow @Entity(tableName = "notes") data class Note( @PrimaryKey(autoGenerate = true) val id: Int = 0, val content: String ) @Dao interface NoteDao { @Query("SELECT * FROM notes") fun getAllNotes(): Flow<List<Note>> @Insert suspend fun insert(note: Note) } @Database(entities = [Note::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun noteDao(): NoteDao } // Usage in a ViewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch class NoteViewModel(private val dao: NoteDao) : ViewModel() { private val _notes = MutableStateFlow<List<Note>>(emptyList()) val notes: StateFlow<List<Note>> = _notes init { viewModelScope.launch { dao.getAllNotes().collectLatest { list -> _notes.value = list } } } }
Remember to collect the Flow in a coroutine scope, like ViewModelScope, to get updates.
Room automatically emits new data when the database changes, no extra code needed.
Use StateFlow or LiveData in your UI layer to observe the Flow.
Room with Flow lets your app react to database changes automatically.
Use Flow in DAO queries to get reactive streams of data.
Collect the Flow in a coroutine scope to update your UI smoothly.
Practice
Flow with Room in Android apps?Solution
Step 1: Understand Flow's role in Room
Flow provides a stream of data that emits updates when the database changes.Step 2: Connect Flow to UI updates
Collecting Flow in a coroutine lets the UI reactively update without manual refresh.Final Answer:
It allows the app to automatically update UI when database data changes. -> Option BQuick Check:
Flow = reactive UI updates [OK]
- Thinking Flow speeds up queries
- Confusing Flow with encryption
- Assuming Flow reduces app size
Solution
Step 1: Identify return type for reactive data
Flow is the correct type for a reactive stream of user lists.Step 2: Compare other options
List<User> is static, LiveData<User> is not Flow, User is a single object.Final Answer:
fun getUsers(): Flow<List<User>> -> Option CQuick Check:
Flow return type = fun getUsers(): Flow [OK]
- Returning List instead of Flow
- Confusing LiveData with Flow
- Returning single object instead of list
fun getAllTasks(): Flow<List<Task>>
What happens when you collect this Flow in your UI and a new task is inserted into the database?
Solution
Step 1: Understand Flow behavior on data change
Flow emits new data whenever the underlying database query result changes.Step 2: Apply to task insertion
Inserting a new task triggers Flow to emit the updated full list including the new task.Final Answer:
The Flow emits the updated list including the new task automatically. -> Option AQuick Check:
Flow emits updated list on insert [OK]
- Thinking Flow stops on data change
- Expecting only new item emission
- Assuming Flow throws error on insert
@Query("SELECT * FROM users")
fun getUsers(): List<User>You want reactive updates but your UI does not update after data changes. What is the problem?
Solution
Step 1: Identify return type issue
Returning List<User> gives a static snapshot, no reactive updates.Step 2: Fix return type for reactive data
Changing return type to Flow enables reactive updates on data change.Final Answer:
The function should return Flow<List<User>> instead of List<User>. -> Option AQuick Check:
Return Flow for reactive updates [OK]
- Forgetting to use Flow return type
- Missing @Query annotation (not the case here)
- Not using coroutine to collect Flow
1. DAO function: ? 2. Collect Flow in UI: ?
Solution
Step 1: Choose correct DAO return type
Flow<List<Note>> provides reactive stream of note lists.Step 2: Collect Flow properly in UI
Use lifecycleScope.launch to collect Flow and update UI reactively.Final Answer:
1. fun getNotes(): Flow<List<Note>> 2. lifecycleScope.launch { dao.getNotes().collect { updateUI(it) } } -> Option DQuick Check:
Flow + coroutine collection = reactive UI [OK]
- Returning List instead of Flow
- Not collecting Flow in coroutine
- Confusing LiveData with Flow
Ready to prove it?
Pass the test and this pattern moves unknown
