Data Persistence With Room

Learn how to persist data in your Android app using the Room SQLite wrapper from Google. By Andrej Vukelic.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Let the Data Flow

Back in Dao section you saw that the method annotated with @Query has return type of Flow. Flow allows you to create a continuous connection to the database so you don’t have to make a query everytime you change something. Instead, it will do the job for you.

In reactive paradigm, when a source of the data changes, all the subscribers immediately get the updated data. In this case, the source is the database, and whenever you make a change in terms of inserting, updating or deleting the record from the database, all the active subscribers will get the new state for the query you’ve requested.

Inspect CategoryListScreen under the package com.kodeco.listmaster.listcategory and in the method CategoryListScreen to see how we subscribed to the stream of data that starts at CategoryDao interface in the CategoryListViewModel by calling the getAll method. Using the line of code: val categories by viewModel.categories.collectAsState(initial = emptyList())

Build the app, add a few categories and then try to delete some of them. Observe that the change is visible immediately on the list screen.

Now, close the app and try to run it again. You’ll see all the categories remain visible.

Android Studio Database Inspector

A useful tool in terms of seeing what is the current state of the application’s database is the Database Inspector which arrived with the Android Studio version 4.1. Also, a prerequisite to use this tool is to have an app running on API level 26+.

Find it under the tab App inspection in the bottom left corner navigation. Check the next screenshot:

App inspection tab location in AS

Now, run the app. It’ll select the process and give you the option to inspect what you have in the database.

database inspector layout

In the above screenshot, notice your database contains list_categories table. Double-click it to see all of the records currently stored in the table.

A cool feature allows you to track how your database behaves when you execute changes on the dataset.

Live updates checkbox position

In the previous screenshot, click the checkbox for the live updates. Mark it and add some categories. Not only are they instantly visible within the app, changes are instantly made within database inspector too. That allows you to do all the database debugging you need.

Last but not least, if you’re a developer working on an app with no Room implementation yet (I hope you’re not in that trouble), in the next section, you’ll get the answer to how to migrate it from SQLite to Room.

Migrate from SQLite to Room

First, if you’re using SQLite and not Room, you’ll need to understand why it’s awesome for you to switch to it.

  • Compile-time verification of SQL queries
  • Convenience annotations that minimize repetitive and error-prone boilerplate code
  • Streamlined database migration paths

Be aware, if you’re having a bunch of data in the database, you should make a gradual progress in migration.

Check this article for the more information.

First, to migrate from SQLite to Room, you should update the dependencies within your app’s build.gradle file.

Add dependencies as it’s mentioned in the Getting Started section.

Next, update all model classes to data classes and create DAOs for them.

After that, create a migration from the old version to the new one, so Room knows how to migrate all the data and work with it. To do that, you’ll need the next snippet of code:

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        // Empty implementation, because the schema isn't changing.
    }
}

Migration can be empty as long as the database scheme is not changed.

At the end, you’ll need to create the Database instance as it’s mentioned in the Database Instances section of this article, but also you’ll need to append .addMigration(MIGRATION_1_2) before you call .build() on your Room.databaseBuilder.

Although this process doesn’t look complicated, test your migration thoroughly and confirm that everything works perfectly.

Now that you know how to migrate your SQLite database to Room, check the next section and see what other Room features can be added for your app to run smoother.

Where To Go From Here?

Download the final project using the link at the top or bottom of this tutorial.

There’s a lot more to learn and do with Room!

  • Migrations for making changes to an existing data store.
  • Indexes to make queries faster.
  • Type Converters to make it easier to map database types to your own custom types.

Stay tuned for future Room tutorials where these will be covered. :]

If you’re just getting started with data persistence on Android and want some more background, check our Saving Data on Android video course, which covers SharedPreferences, saving to files, SQLite and migrations, and also persisting using Room along with other Android Architecture Components such as ViewModel and LiveData.

As a challenge, you can also try:

  • Adding the ability to delete a list category.
  • Creating an onClick event in each category that allows you to edit the category and save it to your database.

Share your comments, findings or ask questions in the comments below or in the forums. I hope you enjoyed this tutorial on data persistence with Room!

Puppy