【问题标题】:Android: onUpgrade not calling at database upgradeAndroid:onUpgrade 不在数据库升级时调用
【发布时间】:2013-12-10 03:41:22
【问题描述】:

我正在开发我的应用程序的第二个版本。我遇到了一个问题。

在我的应用程序中,数据库位于资产文件夹中。现在我想从第二个版本的 assets 文件夹中更新我的数据库。

我尝试将代码升级为:

// Data Base Version.
private static final int DATABASE_VERSION = 2;

我将版本从 1 更改为 2。

//构造函数

public DataBaseHelperClass(Context myContext) {     
    super(myContext, DATABASE_NAME, null ,DATABASE_VERSION);
    this.context = myContext;
    //The Android's default system path of your application database.
    DB_PATH = "/data/data/com.example.myapp/databases/";
}

// 创建数据库

public void createDataBase() throws IOException{
    //check if the database exists
    boolean databaseExist = checkDataBase();

    if(databaseExist){
        this.getWritableDatabase();
    }else{
        this.getReadableDatabase();
        try{
            copyDataBase();
        } catch (IOException e){
            throw new Error("Error copying database");
        }
    }// end if else dbExist
} // end createDataBase().

//检查数据库

public boolean checkDataBase(){
    File databaseFile = new File(DB_PATH + DATABASE_NAME);
    return databaseFile.exists();        
}

// 从资产中复制数据库

private void copyDataBase() throws IOException{ 
    //Open your local db as the input stream
    InputStream myInput = context.getAssets().open(DATABASE_NAME); 
    // Path to the just created empty db
    String outFileName = DB_PATH + DATABASE_NAME; 
    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName); 
    //transfer bytes from the input file to the output file
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close(); 
}

//打开数据库

public void openDataBase() throws SQLException{      
    //Open the database
    String myPath = DB_PATH + DATABASE_NAME;
    sqliteDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);  
}

//关闭数据库

@Override
public synchronized void close() { 
    if(sqliteDataBase != null)
        sqliteDataBase.close(); 
    super.close(); 
}

@Override
public void onCreate(SQLiteDatabase db) {
    // No need to write the create table query.
    // As we are using Pre built data base.
    // Which is ReadOnly.
}

// 更新数据库时。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if(newVersion>oldVersion){
        context.deleteDatabase(DATABASE_NAME);
        try {
            copyDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {

    }
}

但问题是,在设备中执行 apk 后数据库没有更新。 现在我该怎么办。

我的应用程序的第一个版本已上市。第二版不知道怎么更新数据库。

请您提出宝贵的建议指导我,我正在申请中,无法移动。

编辑: onUpgrade 未调用。当我尝试在 onUpgrade 的第一行打印日志但未打印时。所以问题是,onUpgrade 没有调用。

【问题讨论】:

    标签: android database sqlite android-sqlite sql-update


    【解决方案1】:

    为了升级您的数据库,您需要通过操作我发现的架构来正确地做这两个问题的答案都很有用...

    Upgrading database version automatically

    【讨论】:

    • 实际上我想删除数据库并再次从资产文件夹中复制它。应用程序在 UI 中更新,但数据库没有?你能帮我解决这个问题吗?
    【解决方案2】:

    这个链接主要回答了这个问题:Why is onUpgrade() not being invoked on Android sqlite database?

    onUpgrade() 将在getWriteableDatabase()getReadableDatabase() 中调用,因此如果您从不专门打开数据库进行写入或读取,则必须手动调用onUpgrade() 或打开您的数据库。

    【讨论】:

    • 您能否详细说明您的建议。因为我没有从哪里调用 onUpgrade(),或者该做什么。
    • 在哪里调用 createDatabase()?因为在那里您调用 getWriteableDatabase() 和 getReadableDatabase() 但我也无法分辨“this”是什么对象。调用 onUpgrade() 应该足够了。
    【解决方案3】:

    要测试您的 onUpgdate,您应该:

    1. 安装旧版本的应用程序。启动它并让它创建一个数据库。
    2. 安装新版本的应用程序。这应该使用特殊的 adb 命令来完成:adb install -r-r 键模拟应用更新过程。没有-radb install 只是删除旧版本并安装新版本,因此不会调用 onUpgrade。

    但你最好为此编写一个测试。谷歌一下。

    【讨论】:

      【解决方案4】:

      我得到了答案。我所做的更改仅在构造函数中:

      public DataBaseHelperClass(Context context) {     
      super(context, DATABASE_NAME, null ,DATABASE_VERSION);
      this.myContext = context;
      //The Android's default system path of your application database.
      DB_PATH = "/data/data/com.example.myapp/databases/";
      }
      

      它对我有用。

      【讨论】:

      • 你改变了什么?
      【解决方案5】:

      如果我们通过复制方法使用现有数据库,我们必须将当前数据库版本设置为 SQLiteDatabase 实例。并且每次升级应用调用getWritableDatabase(),都会调用onUpgrade()函数。

      public void createDataBase() throws IOException {
          boolean dbExist = checkDataBase();
          Logger.debug(TAG, "checkDataBase dbExist: " + dbExist); 
          if (dbExist) {
              this.getWritableDatabase();
          } else {
      
              // By calling this method and empty database will be created into
              // the default system path
              // of your application so we are gonna be able to overwrite that
              // database with our database.
              this.getWritableDatabase();
      
              try {
      
                  copyDataBase();
                  Logger.debug(TAG, "copyDataBase SUCCESS"); 
              } catch (IOException e) {
      
                  throw new Error("Error copying database");
      
              }
          }
      
      
      public SQLiteDatabase openDataBase() throws SQLException {
           String path = mContext.getDatabasePath(DB_NAME).getPath();
          mDataBase = SQLiteDatabase.openDatabase(path, null,
                  SQLiteDatabase.OPEN_READWRITE);
          mDataBase.setVersion(DB_VERSION);
          return mDataBase;
      

      }

      【讨论】:

      • " 每次升级应用调用 getWritableDatabase() 时,都会调用 onUpgrade() 函数。谢谢,节省了我很多时间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-23
      • 2014-01-28
      相关资源
      最近更新 更多