How to use Room Persistence Library with pre-populated database?
I'd like to use Room with a pre-populated database, but I can't understand how to tell Room where to find my database.
I've now put it in src/main/assets/databases
and when I create the instance for the Room database I create it this way:
Room.databaseBuilder(
getApplicationContext(),
AppDatabase.class,
"justintrain.db"
)
.allowMainThreadQueries()
.build();
This way tho, I think it's creating a new database every time, or anyways, it's not using the pre-populated one.
How can I make it to find my database?
This is how I solved it, and how you can ship your application with a pre-populated database (up to Room v. alpha5)
put your SQLite DB
database_name.db
into theassets/databases
foldertake the files from this repo and put them in a package called i.e.
sqlAsset
-
in your
AppDatabase
class, modify your Room's DB creation code accordingly:Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "database_name.db") .openHelperFactory(new AssetSQLiteOpenHelperFactory()) .allowMainThreadQueries() .build();
Note that you have to use "database_name.db"
and not getDatabasePath()
or other methods: it just needs the name of the file.
UPDATE (Nov 7th 2019)
Room now supports using a pre-packaged database out of the box, since version 2.2.0
https://developer.android.com/jetpack/androidx/releases/room#2.2.0
Solution before version 2.2.0: Simple solution without any other external libraries.
Room relies on the existing Android framework code to create or open a database. If you look into the source code of FrameworkSQLiteOpenHelper
(Room's version of SQLiteOpenHelper
) it internally calls SQLiteOpenHelper.getReadableDatabase()
and other methods wherever needed.
So, the simplest solution is to just copy the DB file from assets directory to mContext.getDatabasePath("my-database.sqlite")
before creating the DB with Room.
In your case, the code looks something like this -
private final String DB_NAME = "my-database.sqlite";
private MyDatabase buildDatabase(Context context) {
final File dbFile = context.getDatabasePath(DB_NAME);
if(!dbFile.exists()) {
copyDatabaseFile(dbFile.getAbsolutePath());
}
return Room.databaseBuilder(context.getApplicationContext(),
MyDatabase.class, DB_NAME)
.build();
}
private void copyDatabaseFile(String destinationPath) {
// code to copy the file from assets/database directory to destinationPath
}
This link has the code needed to copy the DB - link with code
I was having the same problem so I created a library which does exactly that. the accepted answer work but I think it's easier to use a library.
AppDatabase db = RoomAsset
.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "database_name.db")
.build();
Add it to your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Add the dependency
dependencies {
// ... other dependencies
implementation 'com.github.humazed:RoomAsset:v1.0'
}
you can find the library here: https://github.com/humazed/RoomAsset