Android Can';t在三星上将数据库从'n'版本降级为'n-1'

Android Can';t在三星上将数据库从'n'版本降级为'n-1',android,sqliteopenhelper,Android,Sqliteopenhelper,我有一个带有数据库的应用程序,它是使用标准的SQLiteOpenHelper创建和打开的 每当我升级数据库版本时,我也会升级应用程序的版本代码,因此数据库无法下降(数据库版本号总是增加,而不是减少) 通过将android:allowBackup属性设置为false,我禁用了应用程序中的数据库备份 但当我在Play Store上升级应用程序时,我会遇到很多崩溃 无法将数据库从版本n降级到n-1 其中96%的崩溃发生在正在运行的三星设备上。有人知道为什么会发生此问题,更重要的是,如何防止此崩溃吗 我

我有一个带有数据库的应用程序,它是使用标准的SQLiteOpenHelper创建和打开的

每当我升级数据库版本时,我也会升级应用程序的版本代码,因此数据库无法下降(数据库版本号总是增加,而不是减少)

通过将
android:allowBackup
属性设置为false,我禁用了应用程序中的数据库备份

但当我在Play Store上升级应用程序时,我会遇到很多崩溃

无法将数据库从版本
n
降级到
n-1

其中96%的崩溃发生在正在运行的三星设备上。有人知道为什么会发生此问题,更重要的是,如何防止此崩溃吗

我知道我可以覆盖onDowngrade以防止崩溃,但我实际上不明白为什么会调用onDowngrade,因为崩溃是在始终使用数据库最后版本的应用程序上调用的

编辑:添加代码示例,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);
    }
}

这是
SQLiteOpenHelper.ondownggrade(…)
的默认实现:


正如您所看到的,如果调用
super.ondownggrade(…)
,您将得到该异常。您需要自己实现
ondownggrade
,而无需调用
super.ondownggrade
。出于完整性的考虑,应该始终实现该应用程序,因为无法保证何时调用该应用程序-用户更改为使用旧版本的应用程序听起来很奇怪,但可能会出现类似的情况。你知道例外情况来自哪个版本的应用程序吗?

你在@etan答案中的评论:

为什么毫无理由地要求降级

有绝对的理由,

public static final int DB_V5_USAGE_TABLE = 5;

public static final int DB_VERSION = DB_V5_USAGE_TABLE;
您的
DB_版本
保存
5
,并且在构造函数中传递该值。显然,版本的参数应该大于以前的版本,否则您将收到此消息

正如@etan所表达的,如果需要降级版本,则需要正确地覆盖
ondownggrade
方法,而不是再次抛出错误


您可能知道这一点,因此请尝试记住以前的版本,或尝试传递数据库版本参数的
6
或更高版本。

您能看到这些崩溃是否来自根设备吗?在根设备上,如果用户选择99.9%的设备未根设备,则可以降级应用程序。您是否在项目中的某个位置使用带有版本参数的
SQLiteOpenHelper
?如果要重写
SQLiteOpenHelper
,请确保使用最新版本nope在构造函数中调用super,SQLiteOpenHelper使用静态最终常量int作为其版本参数。此外,如果是这种情况,它将在所有类型的设备上崩溃,而不仅仅是在三星上。您忘记为这些崩溃添加stacktrace。这会更明显一点。这太明显了,我甚至没有注意到超级方法的调用。。。注意:最后的问题是没有必要的,要降级DB(出于任何原因),这需要实现,升级也是如此。如果你读过我的问题,我说我知道我可以覆盖onDowngrade方法。我的问题是为什么毫无理由地叫onDowngrade!你能看到这些崩溃来自哪个应用版本吗?这可能会给你一些提示——如果是最新版本,系统正在做一些奇怪的事情。似乎只有三星设备上的数据库版本被奇怪地降级了。
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    throw new SQLiteException("Can't downgrade database from version " +
            oldVersion + " to " + newVersion);
}
public static final int DB_V5_USAGE_TABLE = 5;

public static final int DB_VERSION = DB_V5_USAGE_TABLE;