【问题标题】:onUpgrade is not being called at first time in android SQLiteOpenHelper在android SQLiteOpenHelper中第一次没有调用onUpgrade
【发布时间】:2013-12-04 04:59:44
【问题描述】:

我面临一个非常奇怪的问题。我正在开发一个以 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

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

【问题讨论】:

  • onUpgrade 只有在有旧数据库要升级时才会被调用。
  • @CL。是的,这似乎合乎逻辑,但它不仅仅在第一次调用。
  • 数据库版本肯定会发生变化,因为我已经通过拉数据库文件检查了 PRAGMA user_version 查询。
  • 嗨 Raj,我面临着完全相同的问题。你有什么解决办法吗?请告诉我。

标签: android sqlite sqliteopenhelper


【解决方案1】:

试试这个方法

当您使用DBHelper 类时,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);
    }

}

【讨论】:

  • 我正在覆盖 onCreate() 但我什么也没做。这是我的 onCreate() @Override public void onCreate(SQLiteDatabase db) {}
  • 我正在复制我的 sqlite 文件。我不是通过查询创建数据库。
  • 您可以在onUpgrade()方法中删除版本比较,因为它会在版本值更改时触发。
  • 代码仅用于演示目的。即使我删除了比较块,光标也不会进入 onUpgrade。
【解决方案2】:

您作为初始数据库复制的数据库可能已经将其架构版本设为 2。

其他一些问题:

  • 您应该在完成后存储getWritableDatabase()getReadableDatabase()close() 的结果。

  • 这个

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

    不适用于所有设备。不要硬编码数据库路径。请改用getDatabasePath()

【讨论】:

  • 我只是在这里传递数据库版本super(context, DB_NAME, null, DATABASE_VERSION);,除了这个我没有传递数据库版本。那么架构版本如何更改?但是当我下次检查它时(除了第一次数据库升级)然后 onUpgrade 调用正常。初始时间 DB 版本为 1 然后我将其更改为 2 然后 onUpgrade() 未被调用然后我将其更改为 3 现在调用 db onUpgrade()
  • 我还用 getDatabasePath() 替换了硬编码路径,并正确关闭了所有数据库连接,但与上次相比没有任何变化。
【解决方案3】:

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

显然,如果用户正在更新应用程序,您应该在 on create 方法中创建最新版本的 DB 以进行全新安装,并在 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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-31
    • 2014-09-21
    • 2021-11-05
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    相关资源
    最近更新 更多