Room: Giving Your Android App a Memory


Ever wondered how your favorite apps remember things even when you're offline? Like how your notes app still shows your to-do list without an internet connection? That's the magic of data persistence, and in the Android world, one of the key tools for this is Room.
Why Does Data Persistence Matter?
Imagine you're using a shopping app, and you add items to your cart. Suddenly, your internet connection drops. Without data persistence, your cart might reset, and you'd have to start over. Frustrating, right?
Data persistence ensures that your app retains information, even when:
The app is closed and reopened.
The device is restarted.
There's no internet connection.
This leads to a smoother, more reliable user experience.
Introducing Room: Android's Data Storage Solution
Room is a part of Android Jetpack's suite of libraries. It provides an abstraction layer over SQLite, the traditional database system in Android. Think of Room as a friendly librarian who helps you organize and retrieve your data without needing to understand complex database queries.
Key Benefits of Using Room:
Simplified Database Operations: Room handles the heavy lifting, so you don't have to write complex SQL queries.
Compile-Time Verification: It checks your database queries during development, reducing runtime errors.
Integration with Other Libraries: Room works seamlessly with LiveData, Kotlin Coroutines, and more.
Setting Up Room in Your Android Project
Before diving in, ensure you're using Kotlin for your Android development.
1. Add Dependencies
In your app's build.gradle
file, include the following:
dependencies {
implementation "androidx.room:room-runtime:2.6.1"
kapt "androidx.room:room-compiler:2.6.1"
implementation "androidx.room:room-ktx:2.6.1" // For Kotlin Coroutines support
}
2. Define Your Data Entity
An entity represents a table in your database. For instance, let's create an Item
entity for a shopping app:
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "item_table")
data class Item(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
@ColumnInfo(name = "name") val itemName: String,
@ColumnInfo(name = "price") val itemPrice: Double,
@ColumnInfo(name = "quantity") val quantityInStock: Int
)
Each property corresponds to a column in the database table.
3. Create the Data Access Object (DAO)
The DAO provides methods for accessing the database:
import androidx.room.*
import kotlinx.coroutines.flow.Flow
@Dao
interface ItemDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(item: Item)
@Update
suspend fun update(item: Item)
@Delete
suspend fun delete(item: Item)
@Query("SELECT * FROM item_table WHERE id = :id")
fun getItem(id: Int): Flow<Item>
@Query("SELECT * FROM item_table ORDER BY name ASC")
fun getAllItems(): Flow<List<Item>>
}
4. Set Up the Room Database
This class ties everything together:
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Item::class], version = 1, exportSchema = false)
abstract class ItemRoomDatabase : RoomDatabase() {
abstract fun itemDao(): ItemDao
companion object {
@Volatile
private var INSTANCE: ItemRoomDatabase? = null
fun getDatabase(context: Context): ItemRoomDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ItemRoomDatabase::class.java,
"item_database"
).fallbackToDestructiveMigration().build()
INSTANCE = instance
instance
}
}
}
}
The getDatabase
function ensures that only one instance of the database is created (singleton pattern).
Using Room in Your App
With everything set up, you can now use Room to store and retrieve data. For example, in your ViewModel:
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class InventoryViewModel(private val itemDao: ItemDao) : ViewModel() {
val allItems = itemDao.getAllItems()
fun addItem(item: Item) {
viewModelScope.launch {
itemDao.insert(item)
}
}
fun updateItem(item: Item) {
viewModelScope.launch {
itemDao.update(item)
}
}
fun deleteItem(item: Item) {
viewModelScope.launch {
itemDao.delete(item)
}
}
}
This ViewModel interacts with the DAO to perform database operations asynchronously
Room in Offline Scenarios
One of Room's strengths is handling offline data. For instance:
Caching: Store data retrieved from the internet so users can access it later without a connection.
User Input: Save user-generated content locally and sync it when the device is online.
This ensures your app remains functional and user-friendly, regardless of network conditions.
Conclusion
Room simplifies data persistence in Android apps, making it accessible even to those new to development. By abstracting the complexities of SQLite, it allows you to focus on building features rather than managing databases.
Remember, every great app needs a good memory. With Room, you're giving your app just that.
Subscribe to my newsletter
Read articles from nathan kayumba directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

nathan kayumba
nathan kayumba
I'm a passionate software engineer with a strong focus on backend development and mobile app creation. I specialize in building native Android applications using Kotlin and Jetpack Compose. With a background in software engineering, I enjoy solving complex problems and creating seamless user experiences. When I'm not coding, you'll find me immersed in music, constantly seeking inspiration from new sounds. Let's build the future, one app at a time!