Является ли метод onUpgrade
SQLiteOpenHelper
когда-либо называемым? Если да, то когда это называется и чем? Если он не вызывается разработчиками, то почему он там? Что на самом деле происходит с этой функцией? Я видел примеры, когда он отбрасывает все таблицы, но затем в комментарии говорится, что удаление всех таблиц - это не то, что вы должны делать. Какие-либо предложения?Является ли метод onUpgrade когда-либо называемым?
ответ
Он вызывается при построении SQLiteOpenHelper с версией, более новой, чем версия открытой базы данных. Что делать, зависит от изменений в базе данных, которые сделаны между старой и новой версиями. Единственный случай, когда вы не отбрасываете измененную таблицу, - это изменение в примечании больше, чем добавленный столбец. Затем вы можете использовать инструкцию ALTER TABLE, чтобы добавить новый столбец в подпись таблицы.
Если вы используете SQLiteOpenHelper, onUpgrade будет вызываться всякий раз, когда вы меняете версию БД. Для этого необходимо дополнительное требование. Имя db должно оставаться неизменным.
Old Version:
dbName = "mydb.db"
dbVersion = 1
New Version:
dbName = "mydb.db"
dbVersion = 2
в OnCreate поставщика контента создается экземпляр SQLiteOpenHelper, который принимает эти Params. Ваша реализация SQLiteOpenHelper будет выглядеть следующим образом:
public static final class MySQLiteOpenHelper extends SQLiteOpenHelper {
public MySQLiteOpenHelper(Context context, int dbVersion, String dbName) {
super(context, dbName, null, dbVersion);
}
@Override
public void onCreate(SQLiteDatabase db) {
//Code to create your db here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Code to upgrade your db here
}
}
Спасибо !!! Теперь я наконец понял, как использовать onUpgrade :-) – marlar
@ dev.serghini Где вы находите информацию о том, что изменение имени версии БД запускает только 'onUpgrade'? Мне нужно официальное подтверждение этого, и я не могу найти его в официальных java-документах этого метода. – sandalone
, так что возникает новый вопрос: когда изменилась «dbVersion»? делает ли разработчик это? как «appVersion» приложения? – sports
Для тех из вас, кто хотел бы знать точный момент, когда onUpgrade()
вызывается, то во время вызова либо getReadableDatabase()
или getWriteableDatabase()
.
Для тех, кто не ясно, как он обеспечивает его запуск, ответ таков: он запускается, когда обновляется версия базы данных, предоставленная конструктору SqLiteOpenHelper
. Вот пример
public class dbSchemaHelper extends SQLiteOpenHelper {
private String sql;
private final String D_TAG = "FundExpense";
//update this to get onUpgrade() method of sqliteopenhelper class called
static final int DB_VERSION = 2;
static final String DB_NAME = "fundExpenseManager";
public dbSchemaHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
// TODO Auto-generated constructor stub
}
теперь ... onUpgrade()
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
sql = "ALTER TABLE " + fundExpenseSchema.Expense.TABLE_NAME + " ADD COLUMN " + fundExpenseSchema.Expense.FUNDID + " INTEGER";
arg0.execSQL(sql);
}
На самом деле onUpgrade вызывается только при вызове getWriteableDatabase(). –
спасибо за это объяснение –
@DoctororDrive - также вызываемый 'getReadableDatabase()'; оба вызова 'getDatabaseLocked (boolean writeable)' – CJBS
Просмотр всех сообщений и запуск отладки кода он до сих пор не было ясно для меня, когда я хотел бы видеть onUpgrade вызывался. Я начал думать, что у Android был серьезный недостаток.
Информация на этой странице привела меня к моему окончательному решению. Спасибо, куча всем участникам!
Это решило для меня ...
public class DatabaseHelper extends SQLiteOpenHelper {
public static String TAG = DatabaseHelper.class.getName();
private static final int DATABASE_VERSION = 42;
private static final String DATABASE_NAME = "app_database";
private static final String OLD_TABLE = "old_and_useless";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion > oldVersion) {
Log.d(TAG, "cool! you noticed.");
db.execSQL("DROP TABLE IF EXISTS " + OLD_TABLE);
// other calls like onCreate if necessary
} else {
Log.d(TAG, "Hey! didn't you see me?");
}
}
public void checkDatabaseVersion() {
SQLiteDatabase db = this.getWritableDatabase();
// if the DATABASE_VERSION is newer
// onUpgrade is called before this is reached
}
// other code removed for readability...
}
Это правда, что getWritableDatabase() и getReadableDatabase() не приводит к вызову onUpgrade. Я не проверял другие методы, так как они соответствуют требованиям для моих нужд.
Keep чтение, кикер приходит ...
Этот код в моей первоначальной деятельности просветил меня, когда я, наконец, понял, что версия БД обновляла во время моей отладки ... тьфу!
DatabaseHelper dbHelper = new DatabaseHelper(this);
dbHelper.checkDatabaseVersion();
Примечание: вызов конструктора DatabaseHelper обновляет дб версию
После вызова конструктора ДБ был помечен с новой версией. Убейте приложение перед вызовом getWritableDatabase() или getReadableDatabase(), и вы находитесь в новой версии. После этого новые исполнения никогда не вызывают метод onUpgrade, пока DATABASE_VERSION снова не будет увеличен. (вздох! Теперь кажется смехотворным явлением :)
Мое предложение - добавить ранние этапы своего приложения «checkDatabaseVersion()». В противном случае, если вы создаете объект SQLiteOpenHelper, убедитесь, что вы вызываете один из методов (getWritableDatabase(), getReadableDatabase() и т. Д.) До того, как ваше приложение умирает.
Надеюсь, это сэкономит кому-то еще такую же царапину на голове !. ..: р
Глядя в SqliteOpenHelper
исходного кода, мы можем знать onCreate()
, onUpgrade()
и onDowngrade
дозвонились в getWritableDatabase()
или getReadableDatabase()
методе.
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}
public SQLiteDatabase getReadableDatabase() {
synchronized (this) {
return getDatabaseLocked(false);
}
}
private SQLiteDatabase getDatabaseLocked(boolean writable) {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
}
. . . . . .
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
if (db.isReadOnly()) {
Log.w(TAG, "Opened " + mName + " in read-only mode");
}
mDatabase = db;
return db;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) {
db.close();
}
}
}
Он на самом деле называется при вызове getReadableDatabase
или getWritableDatabase
.
Глубокое погружение:
Вы передаете номер версии в конструкторе SQLiteOpenHelper
, который хранится в переменной с именем mNewVersion
. Вот и все. На данный момент ничего не происходит.
Каждый раз, когда вы вызываете getReadableDatabase или getWritableDatabase, он вызывает метод, называемый getDatabaseLocked
. Этот метод получит существующий номер версии базы данных и сравнит его с mNewVersion
.
- Если база данных с указанным именем не существует, он будет вызывать
onCreate
- Если новая версия больше старой версии она будет вызывать
onUpgrade
. - Если новая версия ниже существующей версии, будет выбрано исключение.
- Если они равны, они будут открыты и откроют базу данных.
Что следует писать в onCreate и onUpgrade?
onCreate
должен содержать код, который создает схему в первый раз.
Вы можете оставить onUpgrade
пустой первый раз, так как он не будет называться в первый раз. Если вы хотите изменить структуру таблицы на более позднем этапе, этот код должен войти здесь.
SQLiteOpenHelper.java (Исходный код)
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}
public SQLiteDatabase getReadableDatabase() {
synchronized (this) {
return getDatabaseLocked(false);
}
}
private SQLiteDatabase getDatabaseLocked(boolean writable) {
.
.
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
}
- 1. Является ли WebComponent.removed() когда-либо называемым?
- 2. Является ли конструктор перемещения дважды называемым C++?
- 3. self call onUpgrade метод
- 4. Является ли буфер обмена официально называемым «картонометром» на iOS?
- 5. Является ли автоматическое тестирование еще называемым дымовым испытанием?
- 6. Является ли __attribute __ ((конструктор)) гарантированно называемым ровно один раз?
- 7. Действительно ли метод SQLiteOpenHelper onUpgrade изменяет версию базы данных?
- 8. Существует ли концептуальная разница между так называемым «набором записей» и так называемым «утверждением»?
- 9. Как должен выглядеть мой метод onUpgrade()?
- 10. Как использовать OnUpgrade android
- 11. SQlite onUpgrade
- 12. Как запускается onUpgrade?
- 13. Как сделать метод называемым пассивным до вызова метода
- 14. Экспресс - Сохранение не называемым
- 15. SQLiteOpenHelper onUpgrade() Confusion Android
- 16. Будут ли данные потеряны, когда onUpgrade называется
- 17. Вызов sqlite onUpgrade проблемы
- 18. Вопрос о методе onUpgrade android
- 19. Является ли метод getMethod безопасным?
- 20. Является ли метод onStart() избыточным?
- 21. Является ли виртуальный метод значительным?
- 22. Является ли этот метод потокобезопасным?
- 23. Является ли этот метод асинхронным?
- 24. Является ли метод window.requestFileSystem устаревшим?
- 25. Проверить, является ли метод const
- 26. Проверьте, является ли метод переопределением?
- 27. Является ли метод org.osgi.framework.Version.toString() потокобезопасным?
- 28. Управление часто называемым соединением WCF
- 29. Выбор строк в методе onUpgrade
- 30. Android SQLite OnUpgrade Error
Это изменение также может быть связано с добавлением новых таблиц, и в этом случае вы не сможете удалить существующие таблицы. – CommonsWare
Но как бы узнать заранее, что вы измените таблицу? Или вам просто нужно изменить метод каждый раз, когда вы публикуете обновление. –
Вы знаете, когда вы меняете базу данных и добавляете другой случай в onUpgrade. Поэтому, когда пользователь обновляет приложение, SQLiteOpenHelper знает, что существующая база данных устарела и принимает соответствующее действие. Просмотрите часть источника Android для справки: http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=packages/SettingsProvider/src/com/android/providers /settings/DatabaseHelper.java – ognian