在Android SQLiteOpenHelper中第一次没有调用onUpgrade

时间:2013-12-04 04:59:45

标签: android sqlite sqliteopenhelper

我面临一个非常奇怪的问题。我正在开发一个具有sqlite DB作为其数据库的android应用程序。我正在使用扩展SQLiteOpenHelper的DBAdapter类。我在互联网上搜索但找不到解决方案。

这是我的SQLiteOpenHelper类

public class DBAdapter  extends SQLiteOpenHelper{

         private static DBAdapter mInstance = null;
        /**The Android's default system path of your application database. */
        private static String DB_PATH = "/data/data/com.mydbapp.android/databases/";

        private final static String DB_NAME = "mydb.sqlite";
        private static final int DATABASE_VERSION = 1;
        private static Context myContext;    


        public static DBAdapter getInstance(Context ctx) {

            if (mInstance == null) {
                mInstance = new DBAdapter(ctx);
            }
            return mInstance;
          }
            private DBAdapter(Context context) {     
                super(context,  DB_NAME, null, DATABASE_VERSION);
                DBAdapter.myContext = context;
                     DB_PATH = "/data/data/" +
                             context.getPackageName()+
                "/databases/"; 
            }   

           public void deleteDB()
           {
               myContext.deleteDatabase(DB_NAME);
           }

            public void createDataBase() throws IOException{     
                boolean dbExist = checkDataBase();  
                if(dbExist )
                {
                   this.getWritableDatabase();
                }
                if(!dbExist){
                    this.getReadableDatabase();
                    try {     
                        copyDataBase();
                    } catch (IOException e) {     
                        e.printStackTrace();
                        throw new Error("Error copying database");     
                    }
                }
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
            {
                if (newVersion > oldVersion)
                {
                            System.out.println("DB Upgrade logic")
                        }
            }

现在,当我更改private static final int DATABASE_VERSION = 2;时,不会调用onUpgrade()方法,但是当我更改private static final int DATABASE_VERSION = 3;时,onUpgrade()会起作用。 所以我的问题是,当我将数据库版本从1更改为2时,为什么不调用onUpgrade()方法。 请帮我解决这个问题。

编辑1

我注意到了一个更奇怪的行为。当我最初使用数据库版本1运行应用程序然后再次使用理智的数据库版本(1)安装应用程序时,现在如果我将数据库版本1更改为2,则调用onUpgrade()。我的意思是说我必须使用相同的数据库版本安装应用程序2次然后如果我更改数据库版本,则调用onUpgrade()。

3 个答案:

答案 0 :(得分:1)

试试这种方式

当您使用DBHelper类时,更改db版本时将自动调用onUpgrade() mehtod。您无需与旧版本和新版本进行比较。你可以删除版本的比较。它会帮助你。检查下面的代码以获得更多清晰。

public class DBHelper extends SQLiteOpenHelper {

    // Static Final Variable database meta information

    static final String DATABASE = "empapp.db";
    static final int VERSION = 1;
    static final String TABLE = "emp";
    static final String TABLE_DEPT = "dept";

    static final String C_ID = "_id";
    static final String C_ENAME = "ename";
    static final String C_DESIGNATION = "designation";
    static final String C_SALARY = "salary";

   // Override constructor
    public DBHelper(Context context) {
        super(context, DATABASE, null, VERSION);

   }

    // Override onCreate method
    @Override
    public void onCreate(SQLiteDatabase db) {

        // Create Employee table with following fields
        // _ID, ENAME, DESIGNATION and SALARY
        db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
            + " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
            + C_DESIGNATION + " text, " + C_SALARY + " text )");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        // Drop old version table
        db.execSQL("Drop table " + TABLE);

        // Create New Version table
        onCreate(db);
    }

}

答案 1 :(得分:0)

可能是您要复制的数据库,因为初始数据库已经将其模式版本设置为2。

其他一些问题:

  • 完成后,您应该将getWritableDatabase()getReadableDatabase()close()的结果存储起来。

  • DB_PATH = "/data/data/" +
             context.getPackageName()+
        "/databases/"
    

    不会在所有设备上工作。不要硬编码数据库路径。请改用getDatabasePath()

答案 2 :(得分:0)

好的,你所描述的行为是正确的: 如果DB没有退出,则运行onCreate 如果DB存在 - 它将获取它的版本并将onUpdate运行到您在构造函数中指定的版本。

显然,您希望在创建方法中创建最新版本的数据库以进行全新安装,并且如果用户正在更新应用程序,则在onUpgrade中部分复制代码... 如果你像我一样认为这不是一个很好的代码方法,我建议你这样做:

public const int VERSION = 2;

@Override
public void onCreate(SQLiteDatabase db) {
    // create a first version of your DB in this method only
    db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
        + " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
        + C_DESIGNATION + " text, " + C_SALARY + " text )");
    this.onUpgrade(db, 1, VERSION); // run onUpgrade manually
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Deal with all other versions separatelly
    for(int i = oldVersion + 1; i <= newVersion; i++) {
        switch(i) {
            case 2:
            db.execSQL("ALTER TABLE " + TABLE + " ADD COLUMN " + C_TAXES + " text;");
            break;
        }
    }
}

如果您不想丢失数据,这种方法很有用。如果您不关心数据 - 那么只需在onCreate和onUpgrade中创建最新版本的数据库 - 删除旧数据库并运行onCreate。