问题
I am facing a very strange problem. I am developing an android application that has an sqlite DB as its database. I am using DBAdapter class which extends SQLiteOpenHelper. I have searched on internet but can't find a solution.
Here is my SQLiteOpenHelper class
public class DBAdapter extends SQLiteOpenHelper{
private static DBAdapter mInstance = null;
/**The Android's default system path of your application database. */
private static String DB_PATH = "/data/data/com.mydbapp.android/databases/";
private final static String DB_NAME = "mydb.sqlite";
private static final int DATABASE_VERSION = 1;
private static Context myContext;
public static DBAdapter getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new DBAdapter(ctx);
}
return mInstance;
}
private DBAdapter(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
DBAdapter.myContext = context;
DB_PATH = "/data/data/" +
context.getPackageName()+
"/databases/";
}
public void deleteDB()
{
myContext.deleteDatabase(DB_NAME);
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist )
{
this.getWritableDatabase();
}
if(!dbExist){
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
throw new Error("Error copying database");
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
if (newVersion > oldVersion)
{
System.out.println("DB Upgrade logic")
}
}
Now when I change private static final int DATABASE_VERSION = 2;
then onUpgrade()
method doesn't get invoked, but when I change private static final int DATABASE_VERSION = 3;
then onUpgrade() works.
So my question is that why doesn't it invoke the onUpgrade()
method when I change DB version from 1 to 2.
Please help me resolve this issue.
Edit 1
I have noticed one more strange behavior. When I initially run application with DB version 1 and then again I install application with sane DB version (1) and now if I change DB version 1 to 2, then onUpgrade() is called. What I mean to say is that I have to install application 2 times with same DB version then if I change DB version, onUpgrade() is called.
回答1:
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.
回答2:
Try this way
When you use DBHelper
class, onUpgrade()
mehtod will be automatically called when you change db version. You don't need to compare with old and new version. you can remove comparison of version. it will help you. check below code for more clearification.
public class DBHelper extends SQLiteOpenHelper {
// Static Final Variable database meta information
static final String DATABASE = "empapp.db";
static final int VERSION = 1;
static final String TABLE = "emp";
static final String TABLE_DEPT = "dept";
static final String C_ID = "_id";
static final String C_ENAME = "ename";
static final String C_DESIGNATION = "designation";
static final String C_SALARY = "salary";
// Override constructor
public DBHelper(Context context) {
super(context, DATABASE, null, VERSION);
}
// Override onCreate method
@Override
public void onCreate(SQLiteDatabase db) {
// Create Employee table with following fields
// _ID, ENAME, DESIGNATION and SALARY
db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
+ C_DESIGNATION + " text, " + C_SALARY + " text )");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop old version table
db.execSQL("Drop table " + TABLE);
// Create New Version table
onCreate(db);
}
}
回答3:
Okay, so behaviour you're describing is correct: If DB doesn't exit it runs onCreate If DB exists - it takes it version and runs onUpdate to the version you specify in constructor.
Apparently it is expected for you to create a newest version of DB in on create method for clean install and have code replicated partially in onUpgrade if user is updating app... If you're like me and think it's not a nice approach to dublicate code I suggest you doing this:
public const int VERSION = 2;
@Override
public void onCreate(SQLiteDatabase db) {
// create a first version of your DB in this method only
db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
+ C_DESIGNATION + " text, " + C_SALARY + " text )");
this.onUpgrade(db, 1, VERSION); // run onUpgrade manually
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Deal with all other versions separatelly
for(int i = oldVersion + 1; i <= newVersion; i++) {
switch(i) {
case 2:
db.execSQL("ALTER TABLE " + TABLE + " ADD COLUMN " + C_TAXES + " text;");
break;
}
}
}
This approach is good if you don't want to lose data. If you don't care for data - then just make newest version of DB in onCreate and in onUpgrade - drop old DB and run onCreate.
来源:https://stackoverflow.com/questions/20367205/onupgrade-is-not-being-called-at-first-time-in-android-sqliteopenhelper