When does SQLiteOpenHelper onCreate() / onUpgrade() run?
SQLiteOpenHelper
onCreate()
and onUpgrade()
callbacks are invoked when the database is actually opened, for example by a call to getWritableDatabase()
. The database is not opened when the database helper object itself is created.
SQLiteOpenHelper
versions the database files. The version number is the int
argument passed to the constructor. In the database file, the version number is stored in PRAGMA user_version
.
onCreate()
is only run when the database file did not exist and was just created. If onCreate()
returns successfully (doesn't throw an exception), the database is assumed to be created with the requested version number. As an implication, you should not catch SQLException
s in onCreate()
yourself.
onUpgrade()
is only called when the database file exists but the stored version number is lower than requested in the constructor. The onUpgrade()
should update the table schema to the requested version.
When changing the table schema in code (onCreate()
), you should make sure the database is updated. Two main approaches:
Delete the old database file so that
onCreate()
is run again. This is often preferred at development time where you have control over the installed versions and data loss is not an issue. Some ways to delete the database file:Uninstall the application. Use the application manager or
adb uninstall your.package.name
from the shell.Clear application data. Use the application manager.
Increment the database version so that
onUpgrade()
is invoked. This is slightly more complicated as more code is needed.For development time schema upgrades where data loss is not an issue, you can just use
execSQL("DROP TABLE IF EXISTS <tablename>")
in to remove your existing tables and callonCreate()
to recreate the database.For released versions, you should implement data migration in
onUpgrade()
so your users don't lose their data.
SQLiteOpenHelper onCreate method is not called
public class Database extends SQLiteOpenHelper {
public static SQLiteDatabase db;
public Database(Context context) {
super(context,"db", null, 1);
getReadableDatabase(); // <-- add this, which triggers onCreate/onUpdate
Log.i("DB", "dbManager");
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.i("DB", "dbOnCreate");
// ...
}
// ...
}
Explanation:
The update is only triggered if the db is accessed for writing or reading. Since you don't attempt that, onCreate
is never called.
Usually, you would just call a method of your Database class somewhere (for example for querying entities) and that is the moment when onCreate
/(or onUpdate
) would be called.
Since, you don't have such methods (for now), just call it inside the Database constructor.
Or:
Alternatively, and maybe more clean would be to call getReadableDatabase()
right after the creation of your Database object:
Database db = new Database(this);
db.getReadableDatabase();
When the SQLiteOpenHelper onCreate method is called?
The documentation says:
The database is not actually created or opened until one of getWritableDatabase() or getReadableDatabase() is called.
SQLiteOpenHelper not calling onCreate
In SQLiteOpenHelper, the meaning of 'onCreate' is different from what it is in an Activity. Here,'onCreate' is called only once, which is the first time you create the database. The next time you run the app, the database is already there, so it won't call 'onCreate'. Your object level initialization should be done in the constructor and not in 'onCreate'
To see 'onCreate' being called, either manually delete the db file, or simply uninstall the app.
onUpgrade is not being called at first time in android SQLiteOpenHelper
Likely the database you're copying as the initial database already has it's schema version as 2.
Some other issues:
You should store the result of
getWritableDatabase()
orgetReadableDatabase()
andclose()
it when done.This
DB_PATH = "/data/data/" +
context.getPackageName()+
"/databases/"won't work on all devices. Don't hardcode database paths. Use
getDatabasePath()
instead.
When is a SQLite database initially created in Android?
Database, as file on disk, is created when you call getWritableDatabase
or getReadableDatabase
.
Just read the docs of SQLiteOpenHelper constructor ;-)
SqliteOpenHelper onCreate() method changes being ignored
If you made changes after the database was already made, then you must update the database version number and setup the onUpgrade method to drop and recreate the tables.
You can also remove some parameters from the constructor since they aren't used.
public CardDBHandler(Context context, SQLiteDatabase.CursorFactory factory) {
super(context, CARD_DATABASE_NAME, factory, CARD_DATABASE_VERSION);
}
Then
cardDBHandler = new CardDBHandler(this, null);
onUpgrade and onCreate not being called after changing android.database.sqlite.SQLiteOpenHelper to net.sqlcipher.database.SQLiteOpenHelper
Finally I found the solution for the problem. Instead of calling the migration functionality inside the onUpgrade() method, I added the migration code before the database is queried for the first time (after opening the app):
public static void encrypt(Context ctxt, File originalFile, char[]
passphrase)
throws IOException {
SQLiteDatabase.loadLibs(ctxt);
if (originalFile.exists()) {
File newFile=
File.createTempFile("sqlcipherutils", "tmp", ctxt.getCacheDir());
SQLiteDatabase db=
SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(), "", null, SQLiteDatabase.OPEN_READWRITE);
db.rawExecSQL("ATTACH DATABASE '" + newFile.getAbsolutePath()+ "' AS encrypted KEY '"+String.valueOf(passphrase)+"'");
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted");
int version=db.getVersion();
db.close();
db=SQLiteDatabase.openDatabase(newFile.getAbsolutePath(), passphrase, null, SQLiteDatabase.OPEN_READWRITE);
db.setVersion(version);
db.close();
originalFile.delete();
newFile.renameTo(originalFile);
}
}
I took the solution from this source. Thanks for the author, whoever he is!
Related Topics
Navigate from One Fragment to Another on Click of a Button
Android: Mkdirs()/Mkdir() on External Storage Returns False
How to Disable All User Inputs (Click, Touch) on an Android View
How to Display an Image in Full Screen on Click in the Imageview
Where Is Android_Sdk_Root and How to Set It.
Check Programmatically If App Is Installed on the Device
Android Blur View (Blur Background Behind the View)
How to Get Last Record from Sqlite
Android Check Null or Empty String in Android
App Crashes (Sometimes) With Fatal Signal 11 (Sigsegv), Code 1
How to Refresh a Previous Activity After the Back Button Is Pressed
How to Measure Distance to Object With Camera
Disable Ssl as a Protocol in Httpsurlconnection
Convert File: Uri to File in Android
Edittext Background Base Line Color Changing Based on Its Focus in Android