Help us understand the problem. What is going on with this article?

【Android】特定のDatabaseファイルを簡単に削除する

More than 5 years have passed since last update.

AndroidでSQLiteを使っている場合、時々テーブルの削除(Drop Table)ではなく、Databasesファイル自体を削除したい時がある。
そういった場合android.content.ContextクラスのdeleteDatabaseメソッドを使えば、特定のDatabasesファイルを簡単に削除できます。

Context#deleteDatabaseメソッド

使い方はとても簡単。

// context=Context helper=SQLiteOpenHelper
context.deleteDatabase(helper.getDatabaseName());

引数に削除したいDatabasesファイルのファイル名を渡すだけで削除できます。
※戻り値がbooleanなので、適切に処理する場合は戻り値を確認する
※Databaseファイルをアプリケーションディレクトリの/databasesディレクトリ以外に作成している場合は例外

しかし、このメソッドではDatabaseファイルのjournalファイルが削除対象に含まれていないという問題があります。
※Databasesファイルに関連する全ファイルが削除できていないことを問題視してます

実際にソースを確認してみると、以下のようにjournalファイルは削除対象に含まれていません。
※Android 4.0.4のContextImplクラスの実装
http://tools.oesf.biz/android-4.0.4_r1.0/xref/frameworks/base/core/java/android/app/ContextImpl.java#775

@Override
public boolean deleteDatabase(String name) {
    try {
        File f = validateFilePath(name, false); // DatabaseファイルのObjectを生成
        return f.delete();
    } catch (Exception e) {
    }
    return false;
}

そこで、この問題を解決するためのメソッドが次に説明するものです。

SQLiteDatabase#deleteDatabaseメソッド

API Level 16(Android 4.1-Jelly Bean)からandroid.database.sqlite.SQLiteDatabaseクラスのdeleteDatabaseメソッドが追加されています。
このメソッドは、上記のContext#deleteDatabaseメソッドと同様に指定したDatabasesファイルを削除するメソッドです。
※ちなみに、こちらはstaticメソッドです

Context#deleteDatabaseメソッドと違う点は、以下のようなことです。

  • journalファイルも削除対象に含まれている
  • WAL(Write Ahead Logging)関連のファイル(-shm,-wal)も削除対象に含まれている
  • アプリケーションディレクトリのdatabases配下以外に作成したDatabasesファイルも削除できる(引数がFileオブジェクトのため)

使い方はとても簡単です。

// context=Context helper=SQLiteOpenHelper
SQLiteDatabase.deleteDatabase(context.getDatabasePath(helper.getDatabaseName()));

/databases配下にあるDatabasesファイルを削除したい場合、引数にFileオブジェクトを渡さないといけないので
ContextクラスのgetDatabasePathメソッドで削除したいDatabasesファイルのFileオブジェクトを生成して渡します。

ちなみに、API Level 16以降はContext#getDatabasePathメソッドも内部的にSQLiteDatabase#deleteDatabaseメソッドを使用しています。
※Android 4.1.1のContextImplクラスの実装
http://tools.oesf.biz/android-4.1.1_r1.0/xref/frameworks/base/core/java/android/app/ContextImpl.java#809

@Override
public boolean deleteDatabase(String name) {
    try {
        File f = validateFilePath(name, false);
        return SQLiteDatabase.deleteDatabase(f);
    } catch (Exception e) {
    }
    return false;
}

なので、API Level 16以降はContext#deleteDatabaseメソッドを使った場合、SQLiteDatabase#deleteDatabaseメソッドを使用したのと同じことになります。
ナイスな実装になってますね!

まとめ

あーAPI Level 16からのメソッドかー。
という落ち込み具合がやばいですが、このメソッド別にAPI Level 16に依存したメソッド等を使用してないので、実はSDKの実装をコピペできます。
なぜAPI Level 1 からないんだよーと言いたくなるメソッドなので、API Level 16以下でこのメソッドが欲しくなったらSDKの実装をコピペしてください!
※よくない方法ですが、まあ仕方ない…

余談ですが、今回紹介したメソッドの実装を見ているとdatabases配下に作成したDatabasesファイルを全て作成する!みたいな実装も簡単にできることがわかります。
コードリーティングは大事です!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした