Android での SQLiteDatabase のクローズについて (2)


SQLiteOpenHelper は、同じ SQLiteDatabase オブジェクトを返します。それを踏まえた close() 処理について述べます。

SQLiteOpenHelper は、同じ SQLiteDatabase オブジェクトを返す

以前に、Android での SQLiteDatabase のクローズについて | DeVlog という記事の中で、SQLiteDatabase オブジェクトは適切にクローズすべきであると述べました。

その後、 Android Tips(20):知っておきたいSQLiteデータベースの注意点 (1/2) – MONOist(モノイスト) という記事を見つけました。 (記事の日付は、 2012年 9月なので、私の記事よりずっと前に書かれたものです。)

その記事の 「データベースのクローズについての注意点」という項目の中で、「SQLiteOpenHelper で取得したオブジェクトは同じオブジェクトを返すので、 オブジェクトを close() しないように実装する場合が多い。」との記述があり、気になったので調べてみました。

まず、「SQLiteOpenHelper は内部に SQLiteDatabase オブジェクトを保持し、同じ SQLiteDatabase オブジェクトを返す。」事はソースで確認できました。内部に mDatabase という private フィールドを保持し、それを返すようになっています。

対処の考え方は同じ

ただし、対処の仕方は 以前の記事 の [パターン1] ~ [パターン3] とほぼ同じで、適切に close() するのが良いと思います。

[パターン1]
1つの SQLiteOpenHelper からは、必要時に 1 つのオブジェクトを取得し、不要になったらすぐ close() する。私は基本このスタイルです。

これは、以前の記事そのままです。

因みに、取得した SQLiteDatabase オブジェクトを close() した後、同じ SQLiteOpenHelper の getWritableDatabase で SQLiteDatabase オブジェクトを取得することは問題ありません。この場合は、新しい SQLiteDatabase オブジェクトが生成されます。

[パターン2]
1つの SQLiteOpenHelper から複数のオブジェクトを取得して(同一スレッドで)利用する場合は、全て不要になった時点で(onDestory() 等で)まとめて close() する。そのためには、 SQLiteOpenHelper#close() を使う。(内部の SQLiteDatabase オブジェクトを close() してくれます。)

[パターン3]
1つの SQLiteOpenHelper から取得したオブジェクトを別スレッドで使用する場合は、aquireReference() を使う

[パターン2]の db1 と db2、[パターン3]の mDb1 と mDb2 は、見かけは別のオブジェクトですが実体は同じオブジェクトです。そのため、その扱いは、以前の記事で複数の参照を扱う場合と同じになります。

[参考にしたサイト]

  1. Android Tips(20):知っておきたいSQLiteデータベースの注意点 (1/2) – MONOist(モノイスト)
  2. SQLiteOpenHelper | Android Developers
  3. SQLiteDatabase | Android Developers

[関連記事]
Android での SQLiteDatabase のクローズについて | DeVlog

メールアドレスが公開されることはありません。