Skip to content

How to load a different database file with Room?

Goal

I have an app with plenty of data, with a switch button, which switch the language (french or english) of the entire app. However, some of my data are stored in a Room database. I have two .db files : database_fr.db and database_en.db.

Let’s say the app is currently in french, with the database_fr.db loaded. When the switch button is pressed, I want the app to use the other .db file, to display all the data in english.

What I have tried

I followed this codelab to get familiar with Room, so this is how I loaded the database :

@Database(entities = {/* blabla...*/}, version = 1, exportSchema = true)
public abstract class RoomDatabase extends androidx.room.RoomDatabase {


   /* the Daos */

   private static volatile RoomDatabase INSTANCE;
   private static final int NUMBER_OF_THREADS = 4;
   static final ExecutorService databaseWriteExecutor =
        Executors.newFixedThreadPool(NUMBER_OF_THREADS);

   static RoomDatabase getDatabase(final Context context) {
        if (INSTANCE == null || currentLocaleIsDifferentFromWantedLocale()) {
            synchronized (WordRoomDatabase.class) {
                if (INSTANCE == null || currentLocaleIsDifferentFromWantedLocale()) {
                    // This is where the db files are loaded
                    if(localeWanted().equals("fr")){
                        // Load the french database
                        Log.i("French db file loaded !");
                        INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                                RoomDatabase.class, "database")
                                .createFromAsset("database/database_fr.db")
                                .build();
                    }
                    else if(localeWanted().equals("en")){
                        // Load the english database
                        Log.i("English db file loaded !");
                        INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                                RoomDatabase.class, "database")
                                .createFromAsset("database/database_en.db")
                                .build();
                    }
                }
            }
        }
        return INSTANCE;
    }
}

and then call this method getdatabase() in the constructor of the RoomRepository.java

 RoomRepository(Application application) {
        db = RoomDatabase.getDatabase(application);
        /* other variables */
 }

to finally access it in my Activities with the variable

RoomViewModel roomViewModel = new ViewModelProvider(this).get(RoomViewModel.class);

When the switch button is pressed, I modify the Locale and refresh the current Activity.

The problem

All the texts stored in strings.xml files are displayed in the good language, but all the data stored in the .db file remains in french (default language).

The log "English db file loaded !" is displayed in my terminal so I know the code was executed.

Question

How to update the .db file loaded efficiently ? I feel like I have to uninstall / re-install the app to make the changes effective.

Answer

Using the singleton approach will only even build one of the databases. Once an instance has been retrieved then INSTANCE will no longer be null, so will return the already built database.

Here’s an example of multiple databases but intended for an unknown number (and hence a master database used to store the known/created databases). It does allow switching between databases. So you might be able to adapt/simplify this to suite your needs.

Can Android Room manage multiple databases and create databases from a template database?