简体   繁体   中英

OnUpgrade Android SQLite Database from Assets Folder

I currently have a database that I am using within my Assets folder. I am having issues upgrading it though. Whenever I up the DATABASE_VERSION number it will only update certain times. And when it does upgrade, it crashes at start and I have to reopen the app.

Here is my createDatabase()

public void createDataBase() throws IOException {
boolean dbExist = checkdatabase();
if (dbExist) {
    Log.v("DB Exists", "db exists");
    // By calling this method here onUpgrade will be called on a
    // writeable database, but only if the version number has been
    // bumped
    this.getWritableDatabase();
}
dbExist = checkdatabase();
if (!dbExist) {
    // By calling this method and empty database will be created into
    // the default system path of your application so we are gonna be
    // able to overwrite that database with our database.
    this.getReadableDatabase();
    try {
        copyDataBase();
    } catch (IOException e) {
        throw new Error("Error copying database");
    }
}
}

onUpgrade()

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (newVersion > oldVersion){
        Log.v("Database Upgrade", "Database version is higher than previous.");
        myContext.deleteDatabase(DB_NAME);

}

I want to delete the old database that I was using and just have the new database available to the app layout.

Here is my LogCat when adding createDataBase() to onUpgrade()

03-06 15:17:15.348: V/DB Exists(2150): db exists
03-06 15:17:15.388: V/Database Upgrade(2150): Database version is higher than previous.
03-06 15:17:15.398: D/AndroidRuntime(2150): Shutting down VM
03-06 15:17:15.398: W/dalvikvm(2150): threadid=1: thread exiting with uncaught exception (group=0xb3f6d648)
03-06 15:17:15.418: E/AndroidRuntime(2150): FATAL EXCEPTION: main
03-06 15:17:15.418: E/AndroidRuntime(2150): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.productguide/com.example.productguide.PowersportsEquivalent}: java.lang.IllegalStateException: getDatabase called recursively
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.os.Looper.loop(Looper.java:137)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.ActivityThread.main(ActivityThread.java:5103)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at java.lang.reflect.Method.invokeNative(Native Method)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at java.lang.reflect.Method.invoke(Method.java:525)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at dalvik.system.NativeStart.main(Native Method)
03-06 15:17:15.418: E/AndroidRuntime(2150): Caused by: java.lang.IllegalStateException: getDatabase called recursively
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:204)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at com.example.productguide.DataBaseHelper.createDataBase(DataBaseHelper.java:143)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at com.example.productguide.DataBaseHelper.onUpgrade(DataBaseHelper.java:248)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:257)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at com.example.productguide.DataBaseHelper.createDataBase(DataBaseHelper.java:136)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at com.example.productguide.PowersportsEquivalent.onCreate(PowersportsEquivalent.java:57)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.Activity.performCreate(Activity.java:5133)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
03-06 15:17:15.418: E/AndroidRuntime(2150):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
03-06 15:17:15.418: E/AndroidRuntime(2150):     ... 11 more

While browsing through Google, I have found an answer to my problem.

By adding the code below to my copyDataBase()

SQLiteDatabase checkdb = null;

try{
String myPath = DB_PATH + DB_NAME;
checkdb = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

// Once the DB has been copied, set the new version
checkdb.setVersion(DATABASE_VERSION);
}
catch(SQLiteException e)
{
//database does’t exist yet.
}

AND having the below code within onUpgrade()

if (oldVersion < newVersion){
    Log.v("Test", "Within onUpgrade. Old is: " + oldVersion + " New is: " + newVersion);
    myContext.deleteDatabase(DB_NAME);
    try {
        copyDataBase();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

My database now upgrades to the database and deletes the previous on every change of the DATABASE_VERSION integer.

java.lang.IllegalStateException: getDatabase called recursively

This is caused by calling eg getReadableDatabase() or getWritableDatabase() from onCreate() or onUpgrade() callbacks. The callbacks are invoked as part database opening process, attempting to open it again at that point would be an error that would potentially lead to infinite recursion unless SQLiteOpenHelper detected that and threw this exception.

Further down the stacktrace:

 at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
 at com.example.productguide.DataBaseHelper.createDataBase(DataBaseHelper.java:143)
 at com.example.productguide.DataBaseHelper.onUpgrade(DataBaseHelper.java:248)

So onUpgrade() calls createDataBase() that calls getReadableDatabase() . The code you posted doesn't show that, it's likely some other version of it.

To get tried and tested helper to use with prepopulated databases, consider jgilfelt/sqlite-asset-helper .

I think i have a simpler solution, just add this to your DB Helper class:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    super.setForcedUpgrade(newVersion);
    super.onUpgrade(db, oldVersion, newVersion);
}

This will ignore any previous version existing and replace it with the one in your 'asset' folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM