以前のユーザーがどこから来たかに関係なく、更新を自動的に処理するために、少し異なるアプローチを行いました。最初に、SQLDatabase でメソッド onUpgrade を実装するクラスを作成しました
public abstract class AbstractMigratorHelper {
public abstract void onUpgrade(SQLiteDatabase db);
}
このクラスから、後で宣言するすべての移行ヘルパーが継承されます
私はそれらの1つの例を書きます
public class DBMigrationHelper5 extends AbstractMigratorHelper {
/* Upgrade from DB schema x to schema x+1 */
public void onUpgrade(SQLiteDatabase db) {
//Example sql statement
db.execSQL("ALTER TABLE user ADD COLUMN USERNAME TEXT");
}
}
この後、アップグレード時に実際に呼び出されるクラスにロジックを実装する必要があります。ここでは、次のようなカスタムの DevOpenHelper の以前の DevOpenHelper を削除する必要があります。
public static class UpgradeHelper extends OpenHelper {
public UpgradeHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
/**
* Here is where the calls to upgrade are executed
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/* i represent the version where the user is now and the class named with this number implies that is upgrading from i to i++ schema */
for (int i = oldVersion; i < newVersion; i++) {
try {
/* New instance of the class that migrates from i version to i++ version named DBMigratorHelper{version that the db has on this moment} */
AbstractMigratorHelper migratorHelper = (AbstractMigratorHelper) Class.forName("com.nameofyourpackage.persistence.MigrationHelpers.DBMigrationHelper" + i).newInstance();
if (migratorHelper != null) {
/* Upgrade de db */
migratorHelper.onUpgrade(db);
}
} catch (ClassNotFoundException | ClassCastException | IllegalAccessException | InstantiationException e) {
Log.e(TAG, "Could not migrate from schema from schema: " + i + " to " + i++);
/* If something fail prevent the DB to be updated to future version if the previous version has not been upgraded successfully */
break;
}
}
}
}
そのため、移行ヘルパーの名前を慎重に付ける場合 (つまり、MigrationHelper5 はスキーマ 5 からスキーマ 6 への移行を行います)、このロジックを実装し、すべての MigratorHelper クラスで、実装する必要があるすべての SQL コードを使用して execSQL 呼び出しを実装するだけです。
最後にもう 1 つ注意点があります。proguard を使用している場合、コードを難読化するときにクラス名が変更されるため、クラスごとに名前を検索するメソッドが機能しない可能性があります。Proguard 構成ファイル (proguard-rules.pro) に例外を追加して、AbstractMigratorHelper から拡張されたクラスを除外することを検討してください。
# Avoid errors when upgrading database migrators
-keep public class * extends yourpackage.locationofyourclass.AbstractMigratorHelper