SQLite API(Android SDK)でデータベースを構築した場合、アプリのパフォーマンスを考えると、識別子の共有が必要になってきます。
この点について、まとめました。
※環境:Android Studio Ladybug | 2024.2.1 Patch 2
Kotlin 2.0.0
※サンプルの全体像は「SQLite APIでデータベースを構築」を参照
識別子の共有
データベースのアクセスを開始する前に、データベースと接続の確立(Open)を行います。
データベース識別子は、その結果として得られるものです。
この接続の確立ですが、非常にコスト(処理時間、CPUの能力消費、メモリー消費)の大きい処理です。ドキュメントにそのような説明があります。
ですので、アプリケーション全体のパフォーマンスを考えると、極力、回数を減らす実装が必要となります。
その方法は2つです。
- ・識別子のシングルトン化
- ・識別子をコンポーネント間で共有
シングルトン化
SQLiteOpenHelper(GameDb)はプロパティwritableDatabaseに識別子を保持します。プロパティの参照を行えば、識別子が取り出されます。
writableDatabaseの実態はJavaのSQLiteOpenHelper#getWritableDatabase( )です。Kotlin環境からはval修飾子のプロパティに見えています。
さらに、下位のgetDatabaseLocked( )が識別子の取り出しの本体です。
private SQLiteDatabase mDatabase;
...
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}
...
private SQLiteDatabase getDatabaseLocked(boolean writable) {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
}
... // データベースをオープンする処理
}
...
getDatabaseLocked( )は関数の始めの部分で識別子のシングルトン化の判定を行い、識別子が未取得の場合に限り、接続の確立(Open)を行います。

つまり、SQLite APIにより、識別子はシングルトン化済みです。
コンポーネント間で共有
Applicationクラスを使って、SQLiteOpenHelper(GameDb)インスタンスの共有を行います。
※Applicatinについては「アプリ全体から参照可能なインスタンス(Application)」を参照
class MyApplication : Application() {
val gameDb: GameDb by lazy { GameDb(this) }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name=".MyApplication"
...>
<activity
android:name=".MainActivity"
...>
...
</activity>
</application>
</manifest>
class MainActivity : ComponentActivity() {
private lateinit var gameDb: GameDb
private lateinit var playerFlow: MutableStateFlow<List<Player>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
...
}
gameDb = (application as MyApplication).gameDb
playerFlow = MutableStateFlow<List<Player>>(playerDb.fetchTop10())
}
...
}
Applicationを介して参照するSQLiteOpenHelper(GameDb)インスタンスは、どのコンポーネント(Activity)からも共有され、そこから識別子は取り出されます。
関連記事:
