不关闭游标或数据库对象?

时间:2011-03-02 21:59:10

标签: java android

我在参加此活动后开始一个新的错误,然后回来。当我第一次加载活动时,它不会发生。功能上一切正常......但我仍然得到这个错误。

  

错误/光标(1059):完成a   尚未停用的游标   或关闭。 database =   /data/data/com.roger.testapp/databases/data,   table = null,query = SELECT MAX(_id)   从记录

     

03-02 16:47:21.835:   ERROR /光标(1059):   android.database.sqlite.DatabaseObjectNotClosedException:   应用程序没有关闭光标   或已打开的数据库对象   这里

on onCreate:

    mDbHelper = new CommonDbAdapter(this);
    mDbHelper.open();
    fillData();

fillData()在我的dbhelper中调用fetchNote,游标用于一些事情,如果rowId == 0,这意味着我没有选择一个项目来进入这个活动,我想得到最后一行那张桌子。如果rowId =其他东西,那么我抓住那一行。我认为这个问题出现在这里,我只是不确定。

public Cursor fetchNote(long rowId, String table, String columns) throws SQLException {
    if (rowId == 0) {
        String query = "SELECT MAX(_id) FROM record";
        Cursor cursor = mDb.rawQuery(query, null);
        rowId = 0;     
        if (cursor.moveToFirst())
        {               
          rowId = cursor.getInt(0);                         
        }
    }
    Cursor mCursor =
        mDb.query(true, table, new String[] {KEY_ROWID,
                columns}, KEY_ROWID + "=" + rowId, null,
                null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;

}

在onDestroy中:

super.onDestroy();
    if (mDbHelper != null) {
        mDbHelper.close();
    }

另外,我是startManagingCursor

3 个答案:

答案 0 :(得分:2)

我建议不要返回光标。这是一种稀缺资源。

在n层Java EE中,最佳做法是在创建它们的方法范围内关闭所有持久性资源(Connection,Statement和ResultSet)。将ResultSet映射到对象或集合中并关闭ResultSet。

我不知道Android上是否存在一些特殊内容会使此无效。

答案 1 :(得分:2)

请勿在{{1​​}}中关闭您的数据库。在您完成使用后立即关闭它(确保在关闭数据库之前关闭每个光标)。您可能无法在预期时调用onDestroy。

此外,在您完成使用后,请关闭onDestroy对象。

编辑: 由于您的活动正在管理Cursor,因此您可以考虑停止管理它并关闭Cursor方法中的所有内容,然后在onPause中再次打开所有内容并onResume。如果您可以更改代码,以便不依赖于管理光标的活动,那么您就不需要保留打开的数据库对象并担心它们。

答案 2 :(得分:0)

看一下activity lifecycle - 您可以看到,当您离开活动(onPause)时,如果其他活动需要内存,您的进程将被终止,但当您的用户返回活动,它会再次点击onCreate。这次你打开一个新的CommonDbAdapter(但是你从未关闭过原始的) - 因此当你最终点击onDestroy时,你只会关闭最新的mDbHelper。

正如其他人所说,最好的方法不是将光标从DBHelper传回,使用数据创建对象,关闭光标并将对象传回。一旦你使用了DBHelper,你也可以关闭它,如果你需要再次使用它,你总是可以创建另一个。