33

我在这段代码中收到“完成尚未停用或关闭的光标”错误。该代码用于填充列表视图。

由于这是一个非致命错误,因此没有崩溃,而且一切似乎都正常......但我不喜欢这个错误。

如果我在此代码末尾关闭光标..列表视图保持为空。如果我在 onStop 关闭光标,我会得到同样的错误。

我该如何解决??

private void updateList() { 
        DBAdapter db = new DBAdapter(this); 
        db.open(); 
            //load all waiting alarm 
            mCursor=db.getTitles("state<2"); 
            setListAdapter(new MyCursorAdapter(this, mCursor)); 
            registerForContextMenu(getListView()); 
            db.close(); 
        } 


error : 


E/Cursor  ( 2318): Finalizing a Cursor that has not been deactivated 
or closed. database = /data/data/xxxxxxxxxxxxxxx.db, table = alerts, 
query = SELECT _id, alert_id, 
E/Cursor  ( 2318): 
android.database.sqlite.DatabaseObjectNotClosedException: Application 
did not close the cursor or database 
object that was opened here 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDr­iver.java: 
53) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.j­ava: 
1345) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java­: 
1229) 
.... 
.... 
4

9 回答 9

26

Cursor如果您关闭inonStop()或,您不应该收到该消息onDestroy()。请再试一次。或者,startManagingCursor()在您Cursor从查询中获取后调用,Android 将Cursor自行关闭。

于 2010-06-18T11:41:21.893 回答
13

斯科特,

我遇到了和你一样的问题。在关闭数据库之前,即“db.close()”,确保首先关闭游标,即“mCursor.close()”

像这样:

private void updateList()
{ 
    DBAdapter db = new DBAdapter(this);
    db.open();

    //load all waiting alarm
    mCursor=db.getTitles("state<2"); 
    setListAdapter(new MyCursorAdapter(this, mCursor)); 
    registerForContextMenu(getListView()); 

    // Let's close the cursor.
    mCursor.close();
    db.close(); 
} 

您提到如果您关闭光标,您的列表视图将保持为空。我建议您将信息传递给一个类并将其复制过来(分配内存)然后关闭游标。

于 2010-09-08T20:10:43.810 回答
2

当查询返回游标时,它实际上位于游标中第一条记录的“之前”。适配器将尝试在第一个元素处执行“getItem”,因此它将失败,因为光标未定位在任何位置。

在我的基本适配器中,我在 getViews 上执行 cursorMoveToPosition。这似乎消除了对 movefirst 的需要。

于 2011-02-19T04:56:35.477 回答
1

不要使用 startManagingCursor() 因为这不再是推荐的方法。出现此问题是因为在终结器到达此对象时仍未关闭游标/数据库连接。您可以通过允许加载程序管理游标或通过自己跟踪所有游标/DB/SQLiteOpenHelper 连接并在它们之后进行清理来避免这种情况。

使用加载器相当麻烦,并且需要很多移动部件才能与列表视图结合使用。另一方面,跟踪光标和数据库连接很容易出现人为错误。如果游标/数据库对象的数量很少,我会推荐后一种解决方案。如果没有,让装载机处理您的连接。

于 2012-09-30T12:47:58.350 回答
1

在您创建光标对象的任何位置关闭它。

当您创建游标对象并完成遍历 SQLite 表时,然后在使用后关闭它。游标的这种关闭防止了 logcat 中的异常。

您不会得到任何与完成打开的游标相关的异常。

这解决了我的应用程序中的相同问题。

于 2012-12-28T07:01:09.543 回答
0

我为这个问题苦苦挣扎了两天。我试图让示例代码正常工作,它将从数据库查询返回的游标直接传递给列表适配器 - 没有临时适配器。它拒绝工作 - 只是显示一个空白屏幕 - 直到我在将光标传递给 ListAdapter 之前调用了光标上的“moveToFirst()”。去搞清楚!当我对此发表评论时,它会中断。

只是想我会分享这个来拯救人们和我一样的挣扎。

如果有人能解释为什么会这样,我将不胜感激。到目前为止,我不必在游标上调用 moveToFirst 来让它们正常执行。

于 2010-12-11T12:44:20.123 回答
0

只是遇到了同样的问题,并想让您知道-以防万一....

我不小心调用了我的 fetch 例程两次,因此“丢失”了第一次调用的结果光标。这导致了错误。

于 2011-11-02T10:50:21.183 回答
0

我也一直在关闭光标时遇到问题:

  • 在设置列表视图的适配器后立即关闭光标会导致光标在数据显示之前关闭。

  • 不能使用 startManagingCursor 来管理游标,因为它已被弃用。

  • 新的 cursorLoader 替代 startManagingCursor 似乎是矫枉过正。

  • 按照建议移动光标的位置不起作用。

  • 使任务成为活动的内部类并在活动的 onDestroy 方法中关闭光标有时会起作用,但并非总是如此。

  • 使任务成为活动的内部类并在活动的 onStop 方法中关闭光标似乎正在工作。

我还发现我可以在关闭游标之前关闭数据库和 sqlite open helper。我什至可以在设置列表视图的适配器后立即关闭它们。数据仍将显示。

于 2011-12-01T02:05:42.883 回答
0

开始管理光标(光标);

这解决了我的问题

于 2012-02-01T20:23:12.020 回答