我有一个数据库应用程序,使用标准SQLiteOpenHelper创建和打开。
每当我升级数据库版本时,我也会升级应用程序的版本代码,因此数据库无法关闭(数据库版本号总是增加,永不减少)。
我通过将android:allowBackup
属性设置为false来禁用我的应用中的数据库备份。
但是当我在Play商店升级应用程序时,我遇到了很多崩溃
无法将数据库从版本
n
降级为n-1
这些崩溃中有96%发生在运行的三星设备上。任何人都知道为什么会出现这个问题,更重要的是如何防止这种崩溃?
我知道我可以覆盖onDowngrade以防止崩溃,但实际上我并不理解为什么会调用onDowngrade,因为在总是使用数据库的最后版本的应用程序上调用了崩溃。 / p>
修改:添加了代码示例,FWIW
我的OpenHelper:
public class MyDBHelper extends SQLiteOpenHelper {
private static final String LOG_TAG = MyDBHelper.class.getName();
public static final String DB_NAME = "my_db";
public static final int DB_V1 = 1;
public static final int DB_V2_UNIQUE_IDS = 2;
public static final int DB_V3_METADATAS = 3;
public static final int DB_V4_CORRUPTED_IDS = 4;
public static final int DB_V5_USAGE_TABLE = 5;
public static final int DB_VERSION = DB_V5_USAGE_TABLE;
public MyDBHelper(final Context context, IExceptionLogger logger) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(final SQLiteDatabase db) {
Debug.log_d(DebugConfig.DEFAULT, LOG_TAG, "onCreate()");
db.execSQL(createMyTable());
}
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
Debug.log_d(DebugConfig.DEFAULT, LOG_TAG, "onUpgrade(): oldVersion = " + oldVersion + " : newVersion = " + newVersion);
if (oldVersion < 2) {
Debug.log_d(DebugConfig.DEFAULT, LOG_TAG, "onUpgrade(): upgrading version 1 table to version 2");
db.execSQL(upgradeTable_v1_to_v2());
}
if (oldVersion < 3) {
Debug.log_d(DebugConfig.DEFAULT, LOG_TAG, "onUpgrade(): upgrading version 2 Entry table to version 3");
db.execSQL(upgradeTable_v2_to_v3());
}
}
@Override
@TargetApi(Build.VERSION_CODES.FROYO)
public void onDowngrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
Debug.log_d(DebugConfig.DEFAULT, LOG_TAG, "onDowngrade(): oldVersion = " + oldVersion + " : newVersion = " + newVersion);
super.onDowngrade(db, oldVersion, newVersion);
}
}
我如何初始化它:
public class DatabaseController {
private MyDBHelper mDBHelper;
public void initialize(final Context context) {
mDBHelper = new MyDBHelper(context);
}
}
答案 0 :(得分:8)
这是SQLiteOpenHelper.onDowngrade(...)
的默认实现:
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
throw new SQLiteException("Can't downgrade database from version " +
oldVersion + " to " + newVersion);
}
正如您所看到的那样,如果您打电话给super.onDowngrade(...)
,您将获得该例外。您需要自己实施onDowngrade
,而无需致电super.onDowngrade
。它应该总是为了完整性而实现,因为无法保证它何时可以被调用 - 用户已经改变使用旧版本的应用程序但是可能存在类似情况,这听起来很奇怪。你知道例外来自哪个版本的应用程序吗?
答案 1 :(得分:0)
你在@etan回答中的评论:
为什么绝对没有理由要求onDowngrade? p>
有绝对的理由,
public static final int DB_V5_USAGE_TABLE = 5;
public static final int DB_VERSION = DB_V5_USAGE_TABLE;
您的DB_VERSION
持有5
并在您的构造函数中传递该值。显然,版本的参数应该大于以前的版本,否则您将收到此消息。
正如@etan表示的那样,如果您需要降级版本,则需要正确覆盖onDowngrade
方法,而不是再次抛出错误。
您可能知道这一点,因此请尝试记住以前的版本或尝试传递6
或更高版本的数据库版本参数。