How to include a pre-populated database with Android app

from the CommonsWare Community archives

At December 9, 2018, 6:54am, Shahood asked:

Hi Mr. Murphy,

I’m using Room in my Android app and want to include a pre-populated database file containing 200k+ rows with the app but am unable to figure out how to do it?
I’ve searched for a solution but none of them uses Room except this one library which I still need to give a try to.
I’ve also gone through this complaint filed by u which is still not resolved by Android team.
So, I just wanted to know if there is any workaround to use until a solid resolution is provided by Android team or is it simply impossible to do with a project using Room?

Regards,
Shahood


At December 9, 2018, 12:52pm, mmurphy replied:

See “Packing up a Room”, in Android’s Architecture Components. In Version 0.11 of that book, it appears starting on Page 251.

Admittedly, there are a couple of problems there:

However, it demonstrates the basic concept. Somebody with time and inclination could create a better solution that blends the concepts from SQLiteAssetHelper directly into a SupportSQLiteOpenHelper implementation.


At January 12, 2019, 1:25pm, Shahood replied:

I successfully bundled a pre populated database with the test version of my app in the following way:

    private static MyDatabase create(Context context) {
    final File dbFile = context.getDatabasePath(DB_NAME);

    if(!dbFile.exists()) {
        copyDatabaseFile(context, dbFile);
    }

    return Room.databaseBuilder(
            context.getApplicationContext(),
            MyDatabase.class, DB_NAME)
            .build();

    }

Here I’m using getDatabasePath() to retrieve, well, the database path. But in your feature request, u have requested some documented statement about where Room stores the database, or a method to retrieve that location.

All I wanted to ask is why u don’t consider getDatabasePath() as the method to retrieve that location. This method worked fine for my app but are there any cases where it could provide us with wrong database path in case we are using Room?
I want to follow the same methodology in the production version of my app but before going ahead, I would like to have your advice on how much of a risk is it to use getDatabasePath().

Thanks


At January 12, 2019, 1:39pm, mmurphy replied:

There is no requirement for FrameworkSQLite* classes to use that location. Right now, it happens to just pass your name to the framework SQLiteOpenHelper and related classes. It does not have to do that.

are there any cases where it could provide us with wrong database path in case we are using Room?

If they change the FrameworkSQLite* classes in a strange way, yes. Your approach is probably safe. I was seeking an official statement that is is safe.


At August 30, 2019, 4:38am, Shahood replied:

Hi,

In version 2.2.0-alpha01, a new feature has been added as follows:

Pre-packaged Database : Two new APIs in RoomDatabase.Builder are now available for creating a RoomDatabase given an already populated database file. createFromAsset() is for when the pre-populated database file is in the assets folder of the APK, while createFromFile() is for when the file is in an arbitrary location. The usages of these API change the behaviour of destructive migrations such that during a fallback migration, Room will try to re-copy the pre-populated database if available, otherwise it fallbacks to just dropping and re-creating all tables. b/62185732

Does it really resolve the issue as pointed out in your feature request?

Thanks
Shahood


At August 30, 2019, 10:50am, mmurphy replied:

It would seem to. createFromUri() would be nice, given that files are less common, particularly on Android 10, but my feature request was only looking for createFromAsset(), so I cannot complain. :grin:

I have not tried this feature in the alpha, so I do not know if it has any problems in practice in its current form.


At September 1, 2019, 4:41am, Shahood replied:

Thanks for the reply!

But I think it tells us only where to put the database file in our APK. It doesn’t still provide any official statement on the location where Room stores the database. Should we consider getDatabasePath() 100% reliable now? If yes, how?


At September 1, 2019, 11:05am, mmurphy replied:

Oh, I see what you mean. Yes, that question remains unanswered.

Well, Google uses getDatabasePath() for their copy stuff. So, it is hopefully fairly reliable.