getDatabase вызывается рекурсивно при вставке записи в oCreate моего класса DbHelper

Когда я пытаюсь вставить запись в метод onCreate моего класса DbHelper, который является расширением SQLiteOpenHelper, возникает эта ошибка.
Я нашел несколько похожих тем, таких как эти:
Android getDatabase вызывается рекурсивно
getWritableDatabase, вызываемый рекурсивно
getDatabase, вызываемый рекурсивно, но это не собирается помочь мне.

public class DbHelper extends SQLiteOpenHelper{

    public int x=0;
    public DbHelper(Context context) {
        super(context, "shareholders.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        try {
            sql = "CREATE TABLE IF NOT EXISTS settings (name text,value text)";
            Log.d("Ehsan", sql);
            db.execSQL(sql);


        ContentValues cv = new ContentValues();
        cv.put("name", "Username");
        cv.put("value", "");
        insert("settings", cv);

        cv.put("name", "Password");
        cv.put("value", "");
        insert("settings", cv);

        cv.put("name", "PersonId");
        cv.put("value", "");
        insert("settings", cv);
        } catch (Exception e) {
            xLog.error(e.getMessage());
        }
    }


public long insert(String table,ContentValues cv){
    SQLiteDatabase mydb =this.getWritableDatabase();
    return mydb.insert(table,null, cv);
}

    }

ошибка будет вызвана, когда эта строка кода захочет выполнить:

insert("settings", cv);

Бревенчатая кошка:

11-10 11:46:53.325: W/dalvikvm(19579): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
11-10 11:46:53.325: E/AndroidRuntime(19579): FATAL EXCEPTION: main
11-10 11:46:53.325: E/AndroidRuntime(19579): java.lang.IllegalStateException: Could not execute method of the activity
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.view.View$1.onClick(View.java:3599)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.view.View.performClick(View.java:4204)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.view.View$PerformClick.run(View.java:17355)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.os.Handler.handleCallback(Handler.java:725)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.os.Looper.loop(Looper.java:137)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.app.ActivityThread.main(ActivityThread.java:5041)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at java.lang.reflect.Method.invokeNative(Native Method)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at java.lang.reflect.Method.invoke(Method.java:511)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at dalvik.system.NativeStart.main(Native Method)
11-10 11:46:53.325: E/AndroidRuntime(19579): Caused by: java.lang.reflect.InvocationTargetException
11-10 11:46:53.325: E/AndroidRuntime(19579):    at java.lang.reflect.Method.invokeNative(Native Method)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at java.lang.reflect.Method.invoke(Method.java:511)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.view.View$1.onClick(View.java:3594)
11-10 11:46:53.325: E/AndroidRuntime(19579):    ... 11 more
11-10 11:46:53.325: E/AndroidRuntime(19579): Caused by: java.lang.IllegalStateException: getDatabase called recursively
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:204)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at ClassLibrary.DbHelper.insert(DbHelper.java:76)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at ClassLibrary.DbHelper.onCreate(DbHelper.java:56)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at ClassLibrary.DbHelper.insert(DbHelper.java:76)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at com.example.shareholders.entities.Person.insert(Person.java:99)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at com.example.shareholders.Sync.doSync2(Sync.java:71)
11-10 11:46:53.325: E/AndroidRuntime(19579):    at com.example.shareholders.AppMenu.clickHandler(AppMenu.java:56)
11-10 11:46:53.325: E/AndroidRuntime(19579):    ... 14 more

Что я должен делать?


person ehsan shirzadi    schedule 10.11.2013    source источник


Ответы (1)


Кажется, у вас есть собственный метод insert(). Скорее всего, он вызывает getWritableDatabase(), который вызывает getDatabase(), и выдает это исключение, поскольку onCreate() уже вызывается в контексте getDatabase(). Просто используйте db.insert() напрямую, где db — это объект SQLiteDatabase, переданный вашему onCreate(), без вызова getWritableDatabase(). По сути, это та же проблема и решение, что и во всех трех вопросах, которые вы связали.

Ранее у вашего вопроса была другая, предыдущая проблема, решение которой приведено ниже, с включенным исправлением insert(), указанным выше:

В вашей таблице нет имен столбцов, указанных вами в ContentValues.

В CREATE TABLE settings указаны только столбцы name и value, но вы пытаетесь вставить данные в столбцы Username, Password и personId.

Также полезно регистрировать полные трассировки стека исключений (а не только сообщения) и читать исключения везде, где вы их регистрируете.

Если я правильно понимаю ваше намерение, вам нужны три строки пары "имя-значение", например:

ContentValues cv = new ContentValues();
cv.put("name", "Username");
cv.put("value", "");
db.insert("settings", cv);

cv.clear();
cv.put("name", "Password");
cv.put("value", "");
db.insert("settings", cv);

cv.clear();
cv.put("name", "personId");
cv.put("value", "");
db.insert("settings", cv);

или таблица с одной строкой и заданными столбцами:

sql = "CREATE TABLE IF NOT EXISTS settings (Username text,Password text,personId)";
person laalto    schedule 10.11.2013
comment
Спасибо, приятель, это была моя ошибка, но проблема все еще остается :( Я обновил свой код в своем вопросе. - person ehsan shirzadi; 10.11.2013
comment
@ehsanshirzari Похоже, вы используете пользовательский insert(), который вызывает рекурсию. Обновил ответ. - person laalto; 10.11.2013
comment
Я думаю, проблема в том, что я хочу сделать вставку в onCreate базы данных. Если это запрещено, как я могу это сделать после создания базы данных? - person ehsan shirzadi; 10.11.2013
comment
В SQLiteDatabase нет статического метода вставки. что вы имеете в виду: SQLiteDatabase.insert()? Зарегистрируйте кота в вопросе. - person ehsan shirzadi; 10.11.2013
comment
Используйте экземпляр SQLiteDatabase db, переданный вашему onCreate(). - person laalto; 10.11.2013