2012-05-19 51 views
14

我正在一個android應用程序,我在資產文件夾中使用現有的sqlite數據庫。所以我實際上從該文件夾複製數據庫。用戶還可以保存自己的數據(將任何內容標記爲收藏夾)。sqlite數據庫onUpgrade()不會被調用

我上傳了一個在市場上的版本。現在我想在數據庫中添加一些新數據並上傳新版本。如果用戶從市場上更新應用程序,我想保留用戶數據(來自以前的版本)並添加新數據。我已經做了一些谷歌,發現升級方法應該做的伎倆。但是我正在從代碼更改DATABASE_VERSION,但升級方法沒有得到調用。我想知道我錯過了什麼。這裏是我的代碼:

public class DataBaseHelper extends SQLiteOpenHelper { 

private static String DB_PATH = "/data/data/riskycoder.login/databases/"; 
public static String DB_NAME = "datenbank_EN.sqlite"; 
private SQLiteDatabase myDataBase; 
private final Context myContext; 
private static final int DATABASE_VERSION = 1; 





public DataBaseHelper(Context context) { 
    super(context, DB_NAME, null, DATABASE_VERSION); 
    this.myContext = context; 
} 

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

} 

private boolean checkDataBase() { 
    SQLiteDatabase checkDB = null; 
    try { 
     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE); 
    } catch (SQLiteException e) { 
    } 
    if (checkDB != null) 
     checkDB.close(); 
    return checkDB != null ? true : false; 
} 

private void copyDataBase() throws IOException { 

    InputStream myInput = myContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[2048]; 
    int length; 
    while ((length = myInput.read(buffer)) > 0) { 
     myOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

    //myDataBase.setVersion(DATABASE_VERSION); 
} 

public void openDataBase() throws SQLException { 
    String myPath = DB_PATH + DB_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE); 
    Log.d("Test", "Database version: " +myDataBase.getVersion()); 
} 

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



@Override 
public void onCreate(SQLiteDatabase db) { 
} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    Log.d("Test", "in onUpgrade. Old is: " + oldVersion + " New is: " + newVersion); 


} 

}

+0

*我從代碼改變DATABASE_VERSION .. *,究竟是什麼意思嗎?我看到你用一個常量字段「DATABASE_VERSION」調用了SQLiteOpenHelper的超級構造函數(顯然不能改變),那麼你怎麼改變數據庫版本呢? – Luksprog

+0

在新版本的應用程序中,我已將DATABASE_VERSION更改爲2.因此,在安裝新版本時應調用onUpgrade方法。或者我錯過了什麼? – rawcoder064

+0

首先,您發佈的代碼showa DATABASE_VERSION是1,所以onUpgrade不會被調用。其次,即使它是2,您的onUpgrade也沒有代碼來執行任何操作來更新數據庫。它不會自動發生,你必須這樣做。 – Barak

回答

18

onUpgrade()如果只調用數據庫的變化版本號被檢測到。增加數據庫的版本如下:

private static final int DATABASE_VERSION = 2; 
+0

對onUpgrade所做的所有操作都不會很好,因爲它會吐出日誌消息(至少使用發佈的代碼) – Barak

+1

OP詢問「爲什麼'onUpgrade'方法沒有被調用。「當然,它只會吐出一條日誌消息,因爲他還沒有實現'onUpgrade'。 –

+0

@ AlexLockwood->我已經將DATABASE_VERSION更改爲2,但是在logcat輸出中沒有顯示。我已經通過sqlite瀏覽器創建了數據庫。我應該在創建數據庫時進行任何版本控制嗎? – rawcoder064

2

試試這個(增加DATABASE_VERSION)&的的onUpdate()將被調用:

private static final int DATABASE_VERSION = 2; 
+0

它會被稱爲什麼都不做...... – Barak

+0

@ Barak->我已經在onUpgrade()中放置了log.d語句來測試。但我沒有看到logcat輸出中的任何內容。這意味着onUpgrade不會被調用。在openDataBase()方法我已經把一個log.d語句。即使我將DATABASE_VERSION更改爲2,我也可以看到數據庫版本始終爲1。 – rawcoder064

2

假設你沒有改變DATABASE_VERSION,你還必須把代碼在onUpgrade做到這一點。這不是神奇的,你必須告訴它該做什麼。

在你的情況,你需要:

1)複製舊數據庫(給它一個新的名字)
2)複製在新的數據庫
3)從舊數據庫讀取數據
4)複製任何差異到新的數據庫
5)刪除舊的數據庫

編輯

假設你船的DB的資產目錄,你會複製它的使用,像這樣:

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    // First copy old db 
    InputStream bakInput = getActivity().getAssets().open(dbname); 
    String bakFileName = getActivity().getAssets() + "YourDB.old"; 
    OutputStream bakOutput = new FileOutputStream(bakFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = bakInput.read(buffer)) > 0) { 
     bakOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

    // delete the old db 
    File delDB = new File(getActivity().getAssets() + "YourDB"); 
    boolean deleted = file.delete(); 

    // Copy in the new db 
    InputStream myInput = getActivity().getAssets().open("YourDB"); 
    String outFileName = MAIN_DB_PATH + dbname; 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer)) > 0) { 
     myOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

    // add code here to get changes user has made to db and move them to updated db 

    // delete the old db copy 
    File delDB = new File(getActivity().getAssets() + "YourDB.old"); 
    boolean deleted = file.delete(); 
} 
+0

對不起,我沒有得到你。在我的情況下,我如何複製新的數據庫。你可以請張貼一些代碼我該怎麼做.......對於我的愚蠢問題抱歉... – rawcoder064

+0

@Barak你能幫我嗎我的onUpgrade方法不叫 – Erum

6

您onUpgrade更改爲以下

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

      if(newVersion > oldVersion){      
        myContext.deleteDatabase(DB_NAME); 
      } 
     } 

,改變你的CreateDatabase()像下面,

public void createDataBase() throws IOException{ 

      boolean dbExist = checkDataBase(); 

      if(dbExist){ 
       // By calling this method here onUpgrade will be called on a 
       // writable database, but only if the version number has been increased 

       this.getWritableDatabase(); 
      } 

      dbExist = checkDataBase(); 

      if(!dbExist){ 

       //By calling this method an empty database will be created into the      default system path 
        //of the application so we will be able to overwrite that database with our database. 
       this.getReadableDatabase(); 

       try { 

        copyDataBase(); 

       } catch (IOException e) { 

        throw new Error("Error copying database"); 

       } 
      } 

     } 

最後增加數據庫版本並重新運行它。在撥打getReadableDatabase()或類似功能之前,您不會撥打onUpgrade

希望這有助於

+0

我跟着你的回答,但仍然onUpgrade方法沒有被稱爲可以幫助我 – Erum

相關問題