I'm working on an Android app where you can play "Wordle". I want to be able to use it offline so I have a Room database including all the possible words (currently around 30MB in size). I want to ship that database with my app but I also want to be able to update DB in app updates (adding/removing entries). How can I do that in a efficient way?
My current database manager includes this function:
fun getDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
synchronized(AppDatabase::class.java) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java, "words"
)
.allowMainThreadQueries()
.createFromAsset("words.db")
.build()
}
}
return INSTANCE!!
}
From my understanding this code looks if there is a database and if not creates a new one from the file words.db file in the assets folder. In this process it copies the file into the working directory and then includes it just like a normal Room DB. It seems to me that this process is not very efficient as the DB is copied ever time the process is terminated and the app is restarted. How would I do that more efficiently? And how could I still update the database with an app update?
It seems to me that this process is not very efficient as the DB is copied ever time the process is terminated and the app is restarted
That is not what happens. It only copies the asset one time, if the database was not copied previously.
FWIW, I cover pre-populated databases and Room in this chapter of this free book.
And how could I still update the database with an app update?
While Room can help detect and deal with schema updates, you are on your own for tracking content updates. So, you try something like:
Have a Room entity that represents your database content version. That version could be represented as a date, a version number akin to versionCode
, or something else.
Have your pre-populated database have its version in the table associated with that entity.
Have that same version identifier available to your Kotlin or Java code, such as via BuildConfig
.
After opening the database, use your DAO to query for the content version entity, and compare its value with the one in your Kotlin or Java code. If the one in your code is newer, this indicates that your user has an older database. In that case, you can close the database, delete the database file, then re-open the database. That will trigger Room to create a fresh copy out of the (newer) asset.