Configuring Room’s Database Access
We have used RoomDatabase to set up our database and get access to our DAO(s) for working with our entities. By default, RoomDatabase will use the “framework” implementation of the support database APIs. However:
- We can tell it to use something else
- We can get control as part of the database setup, to configure the database manually, regardless of what support database API implementation we use
Get a Factory
With the framework’s Android SQLite API, many developers elect to use SQLiteOpenHelper as their entry point. This handles creating and upgrading the database in a decent structured fashion. However, SQLiteOpenHelper is not a requirement — developers could use static methods on SQLiteDatabase, such as openOrCreateDatabase(), to work with a SQLiteDatabase without an associated SQLiteOpenHelper.
The equivalent interface to SQLiteOpenHelper in the support database API is SupportSQLiteOpenHelper. However, with the support database API, working with a SupportSQLiteOpenHelper is unavoidable. Whether you use it, or Room uses it, somebody sets up one of these. SupportSQLiteOpenHelper fills a role similar to that of SQLiteOpenHelper, providing a single point of control for creating and upgrading a database.
However, you do not create a SupportSQLiteOpenHelper directly yourself. Instead, you ask a SupportSQLiteOpenHelper.Factory to do that for you. Each implementation of the support database API should have a class that implements the SupportSQLiteOpenHelper.Factory interface:
- The default Room implementation is
FrameworkSQLiteOpenHelperFactory, from theandroidx.sqlite:sqlite-frameworkartifact - SQLCipher for Android has
SupportFactory - Requery has
RequerySQLiteOpenHelperFactory - And so on
How you get an instance of that factory is up to the implementation of the support database API. In the case of FrameworkSQLiteOpenHelperFactory, you just create an instance via a no-parameter constructor. SQLCipher for Android offers three SupportFactory constructors, where the passphrase is among the various parameters.
Regardless, one way or another, you will need to get an instance of a factory.
You can use the factory directly, bypassing all of Room. Other times, you will want to use Room, but have Room use this support database API implementation.
For that, call openHelperFactory() on the RoomDatabase.Builder as part of setting it up:
val db = Room.databaseBuilder(ctxt, StuffDatabase.class, DB_NAME)
.openHelperFactory(SupportFactory(passphrase))
.build()
Here, we are having Room use SupportFactory from SQLCipher for Android. Room will now use SQLCipher for Android, via SupportFactory, for all of its actual database I/O.
We will examine SQLCipher for Android, and its use with Room, more later in the book.
Add a Callback
Regardless of whether we use openHelperFactory() or not, we can also call addCallback() on the RoomDatabase.Builder to supply a RoomDatabase.Callback to use. This callback can get control at two points:
- When the database file is created, via an
onCreate()function on the callback - When the database file is opened, via an
onOpen()function on the callback
In each case, you get a SupportSQLiteDatabase object to use for manipulating the database. Room itself may not be completely ready for use — particularly in the onCreate() callback — which is why you are not passed your RoomDatabase subclass. Instead, you have to work with the database using the support database API directly.
We will see examples of this, in the context of running some PRAGMA statements, later in the book.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.