Verwendung von Room
Dauer: 45 Minuten
- Room-Datenbank erstellen
- Verwendung der Room-Datenbank in der Todo-App
Ziel: Datenbankzugriff mit Room in Android verstehen
Es gibt scheinbar keinen „Best Practice“-Weg, wie Room in einer Compose-App eingesetzt wird. In der Android-Dokumentation, in Codelabs und in Blog-Beiträgen werden unterschiedliche Ansätze vorgestellt (Repository, Factory, Application, usw.).
Wir verwenden hier einen einfachen Ansatz, um möglichst schnell und mit wenigen zusätzlichen Konzepten zu arbeiten. Dabei werden sicherlich einige Best Practices vernachlässigt.
Room-Datenbank erstellen
Wir erstellen eine abstrakte Klasse data/AppDatabase
, die die
Datenbank konfiguriert:
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [Todo::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun todoDao(): TodoDao
}
Diese Klasse werden wir gleich verwenden, aber zunächst passen wir unser ViewModel an, damit es mit der Datenbank arbeiten kann.
ViewModel an Room via TodoDao
anbinden
Unser ViewModel muss wie folgt angepasst werden:
class TodosViewModel(private val dao: TodoDao) : ViewModel() {
private val _todos = mutableStateListOf<Todo>()
val todos: List<Todo> get() = _todos
init {
viewModelScope.launch {
dao.getAllTodos().collect { list ->
_todos.clear()
_todos.addAll(list)
}
}
}
fun add(text: String) = viewModelScope.launch {
val t = text.trim()
if (t.isNotEmpty()) {
dao.insertTodo(Todo(text = t))
}
}
fun toggleAt(id: Long) = viewModelScope.launch {
val current = _todos.firstOrNull { it.id == id } ?: return@launch
dao.updateTodo(current.copy(done = !current.done))
}
}
Wir verzichten hier auf eine Beschreibung der Änderungen,
die neue Konzepte mit sich bringen (Coroutines, viewModelScope
, collect
, usw.). Hier kann ein KI-Tool helfen.
Das Ziel ist, in der App ein Beispiel für die grundlegende Datenbanknutzung mit Room einzuführen. Bei Bedarf sind eigene Recherchen zu den neuen Konzepten notwendig.
Datenbankinstanz initialisieren
Wir initialisieren die Room-Datenbank in der MainActivity
:
class MainActivity : ComponentActivity() {
// eine DB-Instanz pro Prozess
private val db by lazy {
Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"todo-database"
).build()
}
private val vm: TodosViewModel by viewModels {
viewModelFactory {
initializer { TodosViewModel(db.todoDao()) }
}
}
}
Auch hier erklären wir nicht alle neuen Konzepte.
TodoList
umstellen
Schließlich müssen wir noch die TodoList
anpassen, damit
die Primärschlüssel-ID eines Todos in der Liste verwendet wird:
@Composable
fun TodoList(todos: List<Todo>, onToggleAt: (Long) -> Unit, modifier: Modifier = Modifier) {
LazyColumn(modifier) {
items(items = todos, key = { it.id }) { todo ->
TodoItem(
todo = todo,
onCheckedChange = { onToggleAt(todo.id) }
)
}
}
}
Durch die Verwendung eines ViewModels haben wir nun alle wesentlichen Umstellungen vorgenommen, um mit Room zu arbeiten. In unserer App sollten die Todos nun in der Datenbank gespeichert, aktualisiert und auch nach einem App-Neustart noch vorhanden sein.
Database als Singleton
Es wird empfohlen, die Datenbank als Singleton zu verwenden, um nur eine Instanz der Datenbank im gesamten Anwendungsprozess zu haben.
Dazu kann die Datenbank in einer neuen Application
-Klasse
initialisiert werden. Wir erstellen eine Klasse App
auf
der gleichen Paketebene wie MainActivity
:
class App : Application() {
val db: AppDatabase by lazy {
Room.databaseBuilder(this, AppDatabase::class.java, "todo-database").build()
}
}
In der AndroidManifest.xml
muss die Klasse als application
-Name
oben im Element <application>
angegeben werden:
<application
android:name=".App"
... Rest bleibt wie gehabt ...
Schließlich wird die Datenbank in der MainActivity
wie folgt
verwendet:
class MainActivity : ComponentActivity() {
private val db get() = (application as App).db
// Rest wie gehabt
}
Abschließende Bemerkungen
In Android Studio kann auf die Datenbank eines Emulators im
Database Inspector
zugegriffen werden. Dazu View > Tool Windows > App Inspection
öffnen.
Der konzeptuelle Aufbau von Room wirkt anfangs etwas komplex (siehe grafische Darstellung des Aufbaus von Room in der Dokumentation ).
Sobald Room jedoch eingerichtet ist, können Datenbankoperationen einfach und effizient durchgeführt werden. Room bietet eine umfangreiche API, um Datenbankzugriffe zu verwalten und zu optimieren.
In der Android-Dokumentation, in Codelabs und in Sample-Apps finden sich viele verschiedene Ansätze, wie Room eingesetzt wird. Auch KI-Tools liefern unterschiedliche Antworten und Varianten.
Tipp: Aus einer aktuellen Sample-App von Google den Code nachvollziehen (ggf. mit KI erklären lassen), übernehmen und an die eigenen Bedürfnisse anpassen.
Vertiefendes Material
Guide in Android Developer Docs zum Thema Daten und Dateien https://developer.android.com/guide/topics/data
Room in den Android Developer Docs:
Achtung
Room entwickelt sich ständig weiter… (wie alles andere in Android…)
- Guide
- Release Notes mit Neuigkeiten
- In den Android Courses gibt es Abschnitte zu Room
- Codelab
- Ein paar der Code-Samples verwenden Room
PAUSE
Pause an passender Stelle einlegen.
Es kann zwischendurch immer wieder Fragen geben und Bedarf für Hilfestellung geben.