Can't downgrade database from version `n` to `n-1` on Samsung

感情迁移 提交于 2019-12-12 09:34:11

问题


I have an application with a database, created and opened using the standard SQLiteOpenHelper.

Whenever I upgrade the database version, I also upgrade the application's version code, so there is no way for the database to go down (the database version number is always increased, never decreased).

I disabled database backup in my app by setting the android:allowBackup property to false.

But when I upgrade the app on the Play Store, I get a lot of crash

Can't downgrade database from version n to n-1

96% of those crash occur on Samsung device running . Anyone know why this problem occurs, and more importantly how to prevent this crash ?

I know that I can override the onDowngrade to prevent the crash but I actually don't understand why the onDowngrade is called at all as the crash is called on an app that always use the last version of the database.

Edit : Added code sample, FWIW

My 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);
    }
}

And how I initialize it :

public class DatabaseController {

    private MyDBHelper mDBHelper;

    public void initialize(final Context context) {

       mDBHelper = new MyDBHelper(context);

    }
}

回答1:


This is the default implementation of SQLiteOpenHelper.onDowngrade(...):

public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    throw new SQLiteException("Can't downgrade database from version " +
            oldVersion + " to " + newVersion);
}

As you see if you call super.onDowngrade(...), as you do, you'll get that exception. You need to implement onDowngrade yourself, without calling super.onDowngrade. It should always be implemented for the sake of completeness, as there's no guarantee when it might be called - it sounds strange that the user has changed to use an older version of the app but there might be a situation like that. Do you know what version of the app the exceptions come from?




回答2:


Your comment in the @etan answer:

why the onDowngrade was called for absolutely no reason?

There is absolute reason,

public static final int DB_V5_USAGE_TABLE = 5;

public static final int DB_VERSION = DB_V5_USAGE_TABLE;

your DB_VERSION holds 5 and in your constructor, you are passing that value. Obviously argument for version should be greater than the previous version otherwise you will get this message.

As @etan expressed, if you need to downgrade the version you need to properly override the onDowngrade method instead throwing the error again.

You may be knew this, so please try to remember your previous version or try to pass 6 or greater for database version parameter.



来源:https://stackoverflow.com/questions/43200408/cant-downgrade-database-from-version-n-to-n-1-on-samsung

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!