应用程序没有关闭游标,尽管已关闭

Application did not close cursor, despite getting closed

我的 Android 应用程序中有一个 SQLite 数据库。当我执行一项操作时,我总是会得到一个尚未停用或关闭的已完成游标。方法如下:

public String getKey(){
    net.sqlcipher.database.SQLiteDatabase db = this.getWritableDatabase(Login.authPass);
    String selectQuery = "SELECT  * FROM " + STABLE;
    Cursor cursor = db.rawQuery(selectQuery, null); //This is the line that throws the exception
    String s = cursor.getString(1);
    cursor.close();
    db.close();
    return s;
}

这真的很令人沮丧,因为我要关闭 Cursor,它甚至在到达那里之前就抛出异常。我也不知道我在这一行上所做的任何事情是如何被认为是完成光标的。谢谢。

编辑添加Logcat:

02-24 12:28:26.522 12756-12765/com.itsmr.dre2k14 E/Cursor﹕结束未被停用或关闭的游标。数据库 = /data/data/com.itsmr.dre2k14/databases/keys.db, table = null, query = SELECT * FROM keys net.sqlcipher.database.DatabaseObjectNotClosedException: 应用程序没有关闭此处打开的游标或数据库对象 在 net.sqlcipher.database.SQLiteCursor.(SQLiteCursor.java:217) 在 net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53) 在 net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1447) 在 net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1416) 在 com.itsmr.dre_android_clean.KeyTable.getKey(KeyTable.java:41) 在 com.itsmr.dre_android_clean.Login.noConnectValidate(Login.java:218) 在 com.itsmr.dre_android_clean.Login.connect(Login.java:97) 在 java.lang.reflect.Method.invokeNative(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 android.view.View$1.onClick(View.java:3964) 在 android.view.View.performClick(View.java:4640) 在 android.view.View$PerformClick.run(View.java:19421) 在 android.os.Handler.handleCallback(Handler.java:733) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:136) 在 android.app.ActivityThread.main(ActivityThread.java:5476) 在 java.lang.reflect.Method.invokeNative(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 在 dalvik.system.NativeStart.main(本机方法)

看来您应该调用 moveToFirst() 将光标移动到数据库中的第一行。

此外,只需确保这是您想要的,调用 cursor.getString(1); 将获得当前行中的第二列,因为它是从零开始的。 http://developer.android.com/reference/android/database/Cursor.html#getString(int)

此外,最佳做法是在使用游标之前确保游标不为空,数据库操作也请使用 try/catch。

public String getKey(){
 String s = null;

 try{
  net.sqlcipher.database.SQLiteDatabase db = this.getWritableDatabase(Login.authPass);
  String selectQuery = "SELECT  * FROM " + STABLE;
  Cursor cursor = db.rawQuery(selectQuery, null);
  if (cursor != null && cursor.moveToFirst()){
    s = cursor.getString(1);
  }

 } catch (Exception ex) {
    Log.e("MyApp", ex.getMessage());
 } finally
 {
    if (cursor != null) {
       cursor.close();

    }
    if (db != null) {
        db.close();
    }

 }

return s;
}

这个 post 可能也有帮助: cursor.getstring() is getting the wrong field in the database