top of page

Building Android Apps with Kotlin and Room


Building Android Apps with Kotlin and Room

In today's world of mobile app development, efficient data management is crucial for creating high-quality applications. Kotlin, a modern programming language, offers great support for Android development. When combined with Room, an SQLite object-relational mapping (ORM) library, developers can streamline database operations and enhance productivity.


In this blog post, we will explore the fundamentals of working with Kotlin and Room and demonstrate how to leverage their features to build robust and efficient Android applications.


Prerequisites


To follow along with the examples in this blog post, you should have a basic understanding of Kotlin and Android development. Familiarity with SQLite databases would also be helpful. Ensure you have Android Studio installed and set up on your machine.


What is Room?


Room is an Android library that provides an abstraction layer over SQLite, allowing developers to work with databases using Kotlin or Java objects. It simplifies the process of defining and interacting with databases by eliminating boilerplate code and providing compile-time checks for SQL statements.


Room consists of three main components: entities, data access objects (DAOs), and the database itself.


Setting Up Room in Android Project


To begin, create a new Android project in Android Studio or open an existing one. Then, follow these steps to add the necessary dependencies for Room:


1. Open the app-level build.gradle file.


2. Add the following dependencies in the dependencies block:

implementation 'androidx.room:room-runtime:x.y.z'
kapt 'androidx.room:room-compiler:x.y.z'

Replace x.y.z with the latest version of Room available. Make sure to check the official documentation or Maven repository for the most up-to-date version.


3. Sync your project to fetch the new dependencies.


Defining Entities


Entities represent the tables in the database. Each entity class represents a table, and its fields represent the columns. Let's create a simple entity called User:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val email: String
)

Here, we annotate the class with @Entity and specify the table name as "users." The @PrimaryKey annotation marks the id field as the primary key.


Creating a Data Access Object (DAO)


A DAO provides methods to perform CRUD (Create, Read, Update, Delete) operations on the database. Let's create a DAO interface for the User entity:

@Dao
interface UserDao {
    @Insert
    fun insert(user: User)
    
    @Query("SELECT * FROM users")
    fun getAllUsers(): List<User>

    @Query("SELECT * FROM users WHERE id = :userId")
    fun getUserById(userId: Int): User?

    @Update
    fun updateUser(user: User)
    
    @Delete
    fun deleteUser(user: User)
}

In this example, we annotate the interface with @Dao to mark it as a DAO. We define several methods annotated with @Insert, @Query, @Update, and @Delete for different database operations.


Creating the Database


Now, let's create the database class that ties everything together:

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null
        fun getInstance(context: Context): AppDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
            }

        private fun buildDatabase(context: Context) =
            Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                "app_database"
            ).build()
    }
}

Here, we annotate the class with @Database and specify the entities it contains (in this case, only User) and the database version. The AppDatabase class is an abstract class that extends RoomDatabase. We define an abstract method userDao() that returns the DAO interface for the User entity.


We also implement the Singleton pattern to ensure that only one instance of the database is created. The getInstance() method returns the singleton instance of the AppDatabase. If the instance is null, it creates a new instance using the buildDatabase() method.


Performing Database Operations: Now that we have set up the entities, DAO, and database, let's explore how to perform database operations:

val user = User(1, "John Doe", "john.doe@example.com")
val userDao = AppDatabase.getInstance(context).userDao()

// Inserting a user
userDao.insert(user)

// Fetching all users
val allUsers = userDao.getAllUsers()

// Fetching a user by ID
val retrievedUser = userDao.getUserById(1)

// Updating a user
user.name = "Jane Doe"
userDao.updateUser(user)

// Deleting a user
userDao.deleteUser(user)

In the above example, we first create a User object and obtain an instance of the UserDao using the getInstance() method of the AppDatabase class. We can then perform various operations, such as inserting, fetching, updating, and deleting users.


Conclusion


Kotlin and Room provide a powerful combination for working with databases in Android applications. With Room's simplified API and compile-time checks, developers can write efficient and maintainable code.


In this blog post, we covered the basics of working with Kotlin and Room, including setting up dependencies, defining entities, creating DAOs, and performing common database operations. By leveraging these tools, you can streamline your Android app's data management and create robust applications with ease.


Remember to refer to the official documentation for Room and Kotlin for more in-depth information and advanced features.


Happy coding!

Comments


Blog for Mobile App Developers, Testers and App Owners

 

This blog is from Finotes Team. Finotes is a lightweight mobile APM and bug detection tool for iOS and Android apps.

In this blog we talk about iOS and Android app development technologies, languages and frameworks like Java, Kotlin, Swift, Objective-C, Dart and Flutter that are used to build mobile apps. Read articles from Finotes team about good programming and software engineering practices, testing and QA practices, performance issues and bugs, concepts and techniques. 

Monitor & Improve Performance of your Mobile App

 

Detect memory leaks, abnormal memory usages, crashes, API / Network call issues, frame rate issues, ANR, App Hangs, Exceptions and Errors, and much more.

Explore Finotes

bottom of page