2012-05-19 4 views
14

Я работаю над приложением android, где я использовал существующую базу данных sqlite в папке с ресурсами. Поэтому я фактически копирую базу данных из этой папки. Пользователь также может сохранять свои собственные данные (отметьте любой контент как избранный).База данных Sqlite onUpgrade() не называется

Я загрузил версию на рынок. Теперь я хочу добавить новые данные в базу данных и загрузить новую версию. Если пользователь обновляет приложение с рынка, я хочу сохранить данные пользователя (из предыдущей версии) и добавить новые данные. Я сделал несколько google и обнаружил, что метод обновления должен делать трюк. Но я меняю 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 из кода .. * то, что именно это означает? Я вижу, что вы вызываете супер-конструктор 'SQLiteOpenHelper' с постоянным полем' DATABASE_VERSION' (который, очевидно, не может быть изменен), так как именно вы меняете версию базы данных? – Luksprog

+0

В новой версии приложения я изменил DATABASE_VERSION на 2. Поэтому при установке новой версии следует вызывать метод onUpgrade. Или я чего-то не хватает? – rawcoder064

+0

Во-первых, код, который вы отправили showa DATABASE_VERSION, равен 1, поэтому onUpgrade не будет вызываться.Во-вторых, даже если это было 2, ваш onUpgrade не имеет никакого кода, чтобы делать anythign для обновления базы данных. Это не происходит автоматически, вы должны это сделать. – 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-> Я поставил инструкцию log.d в onUpgrade() для проверки. Но я ничего не вижу в выходе logcat. Это означает, что onUpgrade не вызывается. В методе openDataBase() я поставил оператор log.d. Я вижу, что версия базы данных всегда 1, даже если я изменяю DATABASE_VERSION на 2. – rawcoder064

2

Предполагая, что ты изменить DATABASE_VERSION, вы должны поставить код в onUpgrade, чтобы это произошло. Это не волшебство, вы должны сказать, что делать.

В вашем случае вам необходимо:

1) скопировать старую базу данных (дать ему новое имя)
2) скопировать в новой базе данных
3) читать данные из старой базы данных
4) копировать любые различия в новую базу данных
5) Удаление старой базы данных

EDIT

Предполагая, что вы отправляете БД в активах папка будет скопировать его для использования как так:

@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

@ Барак может помочь мне мой метод 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"); 

       } 
      } 

     } 

В конце увеличьте свою версию базы данных и запустите ее снова. onUpgrade не вызывается до звонка getReadableDatabase() или аналогичных функций.

Надеется, что это помогает

+0

Я следовал за вашим ответом, но все же мой onUpgrade метод не называется, может ли помочь мне – Erum

Смежные вопросы