我正在使用SQLite DB编写Android应用程序。
我的实验很少,并且将数据库版本从1更改为2.
然后我的数据库架构变得稳定,因为我没有发布应用程序而且它是我自己使用的
我决定再次将版本更改为1.
我做了全新安装,一切正常。
但是第二次运行会抛出这个错误:
06-05 10:03:35.683: E/AndroidRuntime(9010): android.database.sqlite.SQLiteException: Can't downgrade database from version 2 to 1
06-05 10:03:35.683: E/AndroidRuntime(9010): at android.database.sqlite.SQLiteOpenHelper.onDowngrade(SQLiteOpenHelper.java:361)
为什么这样,毕竟我做了全新安装,DB也应该被删除了。否?
如何将版本再次更改为1?
答案 0 :(得分:16)
在以下情况下抛出此异常:
SQLiteOpenHelper
构造函数的参数)onDowngrade()
未在您的代码中被覆盖。你说新安装后第一次代码工作正常。确保没有其他代码可以将同一数据库文件的版本号再次提升到2。
答案 1 :(得分:1)
如果您希望能够使用版本高于代码可以处理的版本的数据库运行应用程序,则可以自行覆盖onDowngrade()
。
这是onDowngrade()
的默认实现:
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
throw new SQLiteException("Can't downgrade database from version " +
oldVersion + " to " + newVersion);
}
如果您需要覆盖此方法,请阅读this question also。
如果没有覆盖该方法,我们无法在增加和执行后减少SQLite版本。因此,您需要更改回2
或大于2
:
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 2);
}
如果您要更新表格,可能需要传递3
而不是2
,并且每次需要更新表格时,都需要< strong>增加版本(不减少)。
答案 2 :(得分:0)
当需要降级数据库时会发生此异常,但您的SQLiteOpenHelper派生类未实现onDowngrade callback。
答案 3 :(得分:0)
您没有显示创建数据库的位置,这是通常分配数据库版本的位置(即SQLiteOpenHelper ctor)。
您是否有机会在外部文件系统上安装数据库?除非遵循命名约定,否则在删除应用程序时不会删除这些文件。
答案 4 :(得分:0)
您是如何进行全新安装的?
adb install -r
?在这种情况下,您的应用程序数据(包括数据库)将不会被触及。adb uninstall
和adb install
?这将是执行全新安装的正确方法。所有数据都将在uninstall
期间删除,您的数据库将在install
之后的第一次启动后重新创建。但是你在全新安装后的第一次启动中写道,它起作用了。 这只能意味着您仍然可以在某处继续升级到版本2.
答案 5 :(得分:0)
<强>更新强>: 转到应用信息和&gt;存储和清晰的数据也应该存在。
第一次工作但不是第二次工作的一个可能原因可能是第一次运行时没有调用数据库?
同样来自Marshmallow,针对23岁以上的应用的Android应用数据为automatically backed up.,因此您的应用可能会在您不知情的情况下从云中获取以前的数据库。
很遗憾,您无法单独删除应用数据。但是,如果您不介意删除所有应用的备份数据,则可以卸载该应用,然后转到https://myaccount.google.com/dashboard并展开Android部分并删除备份的应用数据。
之后,您应该能够重新安装该应用并获得一个全新的数据库。
这对我有用,但这样做需要您自担风险。
答案 6 :(得分:0)
这意味着已有一个上一个文件,并且您正在尝试创建另一个具有相同名称的文件,您可以更改数据库的名称,或者在您要模拟的设备上卸载该应用程序,然后再次模拟它。
答案 7 :(得分:0)
有同样的问题,我这样解决了。
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.setVersion(oldVersion);
}
答案 8 :(得分:0)
onDowngrade()在您的代码中不会被覆盖。 您应该处理onDownGrade()。
答案 9 :(得分:0)