2012-11-19 93 views
0

我遇到了一个问题,现在我已经苦苦挣扎了好几天。它不断给我一个错误,我的数据库没有关闭。我从我的sql数据库中获取项目,并将它们放在具有自定义适配器的gridview中。如果你点击一个项目,它会带你到另一个类(answer.java)。无所作为并按下后退按钮不会导致错误,但如果我调用某个功能并在此功能后按下后退按钮,则在按下后退按钮时会出现close()错误。 因此,这是确切的错误:数据库没有关闭错误已关闭代码

11-19 19:56:22.485: E/Database(7403): close() was never explicitly called on database '/data/data/com.test.game/databases/quizDb' 
11-19 19:56:22.485: E/Database(7403): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
11-19 19:56:22.485: E/Database(7403): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1847) 
11-19 19:56:22.485: E/Database(7403): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820) 
11-19 19:56:22.485: E/Database(7403): at com.test.game.db.DataBaseHelper.openDataBase(DataBaseHelper.java:117) 
11-19 19:56:22.485: E/Database(7403): at com.test.game.Answer.loadDataBase(Answer.java:179) 
11-19 19:56:22.485: E/Database(7403): at com.test.game.Answer.onClick(Answer.java:240) 
11-19 19:56:22.485: E/Database(7403): at android.view.View.performClick(View.java:2491) 
11-19 19:56:22.485: E/Database(7403): at android.view.View$PerformClick.run(View.java:9086) 
11-19 19:56:22.485: E/Database(7403): at android.os.Handler.handleCallback(Handler.java:587) 
11-19 19:56:22.485: E/Database(7403): at android.os.Handler.dispatchMessage(Handler.java:92) 
11-19 19:56:22.485: E/Database(7403): at android.os.Looper.loop(Looper.java:130) 
11-19 19:56:22.485: E/Database(7403): at android.app.ActivityThread.main(ActivityThread.java:3683) 
11-19 19:56:22.485: E/Database(7403): at java.lang.reflect.Method.invokeNative(Native Method) 
11-19 19:56:22.485: E/Database(7403): at java.lang.reflect.Method.invoke(Method.java:507) 
11-19 19:56:22.485: E/Database(7403): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:861) 
11-19 19:56:22.485: E/Database(7403): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:619) 
11-19 19:56:22.485: E/Database(7403): at dalvik.system.NativeStart.main(Native Method) 

我想我找到了代码,这是造成这个错误的部分,如果我没有在我的answer.java文件调用myDbHelper.insertString(...)了,我没有得到的错误了......

public void insertString(int id, int level, String field, String player) { 

    Cursor c = myDataBase.rawQuery(
      "SELECT * FROM ANSWERS WHERE QUESTION_ID=" + id 
        + " AND PLAYER ='" + player + "'", null); 

    myDataBase = this.getWritableDatabase(); 

    if (c != null) { 
     myDataBase.execSQL("UPDATE ANSWERS SET " + field + "=1" 
       + " WHERE QUESTION_ID=" + id + " AND LEVEL =" + level 
       + " AND PLAYER='" + player + "'"); 
    } else { 
     myDataBase 
       .execSQL("INSERT INTO ANSWERS (level, player, question_id, " 
         + field + ") VALUES ("+ level + ",'" + player + "'," + id + ", 1)"); 
    } 

    c.close(); 
    if (myDataBase != null) { 
     myDataBase.close(); 

    } 

} 

一个我试过,但没有解决它加入这个我answer.java文件的东西:

@Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      if (myDbHelper != null) { 
       myDbHelper.close(); 
      } 
return true; 
     } 

     return super.onKeyDown(keyCode, event); 
    } 

//和.close()在我的databasehelp中er.java是:

@Override 
public synchronized void close() { 
    if (myDataBase != null) 
     myDataBase.close(); 
    if (c != null) 
     c.close(); 
    super.close(); 
} 

希望有人能给我看光!

编辑

@sam您的解决方案给了我这样的:

11-19 19:52:42.735: E/AndroidRuntime(6982): FATAL EXCEPTION: main 
11-19 19:52:42.735: E/AndroidRuntime(6982): android.database.sqlite.SQLiteException: attempt to write a readonly database: UPDATE ANSWERS SET showhint1=1 WHERE QUESTION_ID=18 AND LEVEL =1 AND PLAYER='trst' 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1763) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at com.test.game.db.DataBaseHelper.insertString(DataBaseHelper.java:301) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at com.test.game.Answer.onClick(Answer.java:241) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.view.View.performClick(View.java:2491) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.view.View$PerformClick.run(View.java:9086) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.os.Handler.handleCallback(Handler.java:587) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.os.Handler.dispatchMessage(Handler.java:92) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.os.Looper.loop(Looper.java:130) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at java.lang.reflect.Method.invokeNative(Native Method) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at java.lang.reflect.Method.invoke(Method.java:507) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:861) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:619) 
11-19 19:52:42.735: E/AndroidRuntime(6982):  at dalvik.system.NativeStart.main(Native Method) 
+0

'com.test.game.Answer.onClick(Answer.java:249)'是你打开但未关闭数据库 – zapl

+0

有关系吗?我把它关闭在我的databasehelper.java文件中..我认为它关系它的地方不重要?但即使如此,如我所说,如果我关闭它在我的onkeyDown方法,它仍然给我的错误... –

+0

PS:如果我把myDbHelper.close();在我的answer.java文件中调用insertstring方法后,我仍然有错误..所以我不认为这是问题? –

回答

3
Cursor c = myDataBase.rawQuery(
     "SELECT * FROM ANSWERS WHERE QUESTION_ID=" + id 
       + " AND PLAYER ='" + player + "'", null); 

//Try adding this 
myDatabase.close(); 

myDataBase = this.getWritableDatabase(); 

编辑:尝试做如下改变:

myDatabase.close(); 
myDataBase = this.getWritableDatabase(); 
Cursor c = myDataBase.rawQuery(
     "SELECT * FROM ANSWERS WHERE QUESTION_ID=" + id 
       + " AND PLAYER ='" + player + "'", null); 

//move this to before the rawQuery 
//myDataBase = this.getWritableDatabase(); 
+0

好吧,我不再接受错误..但它也不会将值插入到我的数据库现在...我想它也会关闭c光标,尝试更新哪些不起作用,并且导致事实上,它不插入到我的数据库..这可能吗? –

+0

尝试上面提到的编辑 – arjoan

+0

如何简单地调用'myDataBase.close()'然后'myDataBase = this.getWritableDatabase();'然后只用'rawQuery()'获取光标? (理解这并不解决真正的问题,它只是一个创可贴。) – Sam

0

这与其说是一个答案,一个黑客。但是你可以尝试把数据库关闭在你的数据库帮助程序类的openDatabase方法中。类似以下内容可能会起作用。

if (this.db.isOpen()) { 
     this.db.close(); 
    } 
+0

你的意思是在打开一个新的之前? –

+0

是的,检查它是否打开(而不是空)。如果它是打开的,关闭它然后重新打开。 – Durus

+0

它并没有诀窍...... :( –

2

显然你在多个位置打开数据库:

// myDataBase is already open or else this could not work 
Cursor c = myDataBase.rawQuery(
     "SELECT * FROM ANSWERS WHERE QUESTION_ID=" + id 
       + " AND PLAYER ='" + player + "'", null); 

// You are opening myDataBase again 
myDataBase = this.getWritableDatabase(); 

只需通过你的代码寻找getWritableDatabase()getReadableDatabase()发现,你已经忘记了关闭它的任何位置。 如果您访问数据库很多,请在活动的onResume()中打开一次数据库,然后在onPause()中关闭一次。

+0

但我在同一个方法中关闭了c游标和myDataBase?那么这不是正确的关闭呢? –

+0

嗯,我无法完全猜到发生了什么事你代码中的其他地方...但是当你注释掉'myDataBase = this.getWritableDatabase();'会发生什么? – Sam

+0

我扩展了SQLiteOpenHelper类,我没有自己编写这个方法http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#getWritableDatabase() –