当前位置: 动力学知识库 > 问答 > 编程问答 >

android - getDatabase called recursively

问题描述:

My first time asking a question here, so be gentle, Lol.

Anyway. Ive been working on an Android and my latest build ran flawlessly.. Until yesterday, when IT gave me a new workstation. Since getting this new workstation, I keep getting the following error:

04-11 17:34:53.282: E/AndroidRuntime(789): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.blueharvest/com.example.blueharvest.SettingsActivity}: java.lang.IllegalStateException: getDatabase called recursively

If it helps, I am running this in a virtual device, using platform 4.2.2 and API level 17.

I am really hoping that someone can shed some light on this error, so I can stop ripping my hair out, Lol.

If any other information is needed, please let me know.

Thanks so much,

Brad.

EDIT: Added more of the logcat

04-11 19:25:08.668: E/AndroidRuntime(2748): FATAL EXCEPTION: main

04-11 19:25:08.668: E/AndroidRuntime(2748): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.blueharvest/com.example.blueharvest.SettingsActivity}: java.lang.IllegalStateException: getDatabase called recursively

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.ActivityThread.access$600(ActivityThread.java:141)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.os.Handler.dispatchMessage(Handler.java:99)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.os.Looper.loop(Looper.java:137)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.ActivityThread.main(ActivityThread.java:5041)

04-11 19:25:08.668: E/AndroidRuntime(2748): at java.lang.reflect.Method.invokeNative(Native Method)

04-11 19:25:08.668: E/AndroidRuntime(2748): at java.lang.reflect.Method.invoke(Method.java:511)

04-11 19:25:08.668: E/AndroidRuntime(2748): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)

04-11 19:25:08.668: E/AndroidRuntime(2748): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)

04-11 19:25:08.668: E/AndroidRuntime(2748): at dalvik.system.NativeStart.main(Native Method)

04-11 19:25:08.668: E/AndroidRuntime(2748): Caused by: java.lang.IllegalStateException: getDatabase called recursively

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:204)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)

04-11 19:25:08.668: E/AndroidRuntime(2748): at com.example.blueharvest.DatabaseHandler.setDefaultLabel(DatabaseHandler.java:90)

04-11 19:25:08.668: E/AndroidRuntime(2748): at com.example.blueharvest.DatabaseHandler.onCreate(DatabaseHandler.java:82)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)

04-11 19:25:08.668: E/AndroidRuntime(2748): at com.example.blueharvest.DatabaseHandler.populateFields(DatabaseHandler.java:196)

04-11 19:25:08.668: E/AndroidRuntime(2748): at com.example.blueharvest.SettingsActivity.onCreate(SettingsActivity.java:45)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.Activity.performCreate(Activity.java:5104)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)

04-11 19:25:08.668: E/AndroidRuntime(2748): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)

04-11 19:25:08.668: E/AndroidRuntime(2748): ... 11 more

EDIT: Added code causing the error. setDefaultLabel() is the culprit.

@Override

public void onCreate(SQLiteDatabase db) {

// Create tables

db.execSQL(CREATE_CATEGORIES_TABLE);

db.execSQL(CREATE_CHRGDATA_TABLE);

db.execSQL(CREATE_SETTINGS_TABLE);

setDefaultLabel();

}

/**

*

*/

public void setDefaultLabel() {

// create default label

SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();

values.put(KEY_NAME, "Default");

db.insert(TABLE_LABELS, null, values);

}

网友答案:

Try changing your setDefaultLabel() method to...

public void setDefaultLabel(SQLiteDatabase db)

...then in onCreate(...) simply pass the db parameter into it and get rid of this line...

SQLiteDatabase db = this.getWritableDatabase();

Your code should then look like this...

@Override
public void onCreate(SQLiteDatabase db) {
    // Create tables        
    db.execSQL(CREATE_CATEGORIES_TABLE);        
    db.execSQL(CREATE_CHRGDATA_TABLE);
    db.execSQL(CREATE_SETTINGS_TABLE);
    setDefaultLabel(db);
}

/**
 * 
 */

public void setDefaultLabel(SQLiteDatabase db) {
    // create default label
    ContentValues values = new ContentValues();
    values.put(KEY_NAME, "Default");
    db.insert(TABLE_LABELS, null, values);
}

The problem in your existing code is that onCreate(...) is being passed a reference to the open / writeable database but it then calls setDefaultLabel(...) which attempts to get another writeable reference to the database.

网友答案:

Here is my solution for this: In the Helper, I override 2 methods getWritableDatabase() and getReadableDatabase() like below: Notice that you should not close the database, it may be crashed.

    @Override
    public void onCreate(SQLiteDatabase db) {
        // All your code here .....

        // Add default value for all tables
        isCreating = true;
        currentDB = db;
        generateAllDefaultData();
        // release var
        isCreating = false;
        currentDB = null;
    }

    boolean isCreating = false;
    SQLiteDatabase currentDB = null;

    @Override
    public SQLiteDatabase getWritableDatabase() {
        // TODO Auto-generated method stub
        if(isCreating && currentDB != null){
            return currentDB;
        }
        return super.getWritableDatabase();
    }

    @Override
    public SQLiteDatabase getReadableDatabase() {
        // TODO Auto-generated method stub
        if(isCreating && currentDB != null){
            return currentDB;
        }
        return super.getReadableDatabase();
    }
分享给朋友:
您可能感兴趣的文章:
随机阅读: