完成未停用或关闭的游标非致命错误

Posted

技术标签:

【中文标题】完成未停用或关闭的游标非致命错误【英文标题】:Finalizing a Cursor that has not been deactivated or closed non-fatal error 【发布时间】:2011-03-05 08:14:00 【问题描述】:

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

因为这是一个非致命错误,所以没有崩溃,一切似乎都正常 很好..但我不喜欢这个错误。

如果我在这段代码的末尾关闭光标..列表视图保持不变 空的。 如果我在 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) 
.... 
.... 

【问题讨论】:

【参考方案1】:

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

【讨论】:

谢谢 - startManaginCursor(mCursor) - 修复它....错误总是在活动开始后立即发生..所以在错误之前关闭 onStop 甚至不会被调用。谢谢。 @arnold:也许你想错了Cursor?您没有理由“在活动开始后立即”收到该消息,所以我想您可能是从之前的活动中泄露了 Cursor 或其他内容。 使用 try catch 并在 finally 块中编写代码 cursor.close() 和 cursor.deactivate(); // 仅当您想在稍后阶段查询存储时,否则 cursor.close() 就足够了。 (cursor == null) 也能解决问题 startManagingCursor(Cursor) 已弃用:“将新的 CursorLoader 类与 LoaderManager 一起使用。” 我知道这是一个旧线程,但没有人说显而易见的。他正在创建一个游标,然后立即关闭数据库而不关闭游标。示例代码中 db.close() 之前的 cursor.close() 应该可以解决该问题。这就是在创建 Activity 时发生这种情况的原因。【参考方案2】:

斯科特,

我遇到了和你一样的问题。在关闭数据库之前,即“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(); 
 

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

【讨论】:

如果我将光标返回到自定义光标适配器,它为我创建视图,那么有什么方法可以关闭光标?【参考方案3】:

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

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

【讨论】:

只是对@birdman 的一个补充想法:您的光标可能以前工作过,特别是如果您使用 while(moveToNext)。由于在第一条记录之前返回了一个游标,因此 moveToNext 有效。【参考方案4】:

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

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

【讨论】:

【参考方案5】:

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

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

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

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

【讨论】:

【参考方案6】:

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

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

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

【讨论】:

你应该使用 startManagingCursor 否则你必须照顾光标,即关闭,移动等【参考方案7】:

刚遇到同样的问题,想告诉你——以防万一......

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

【讨论】:

【参考方案8】:

我也遇到了关闭光标的问题:

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

无法使用 startManagingCursor 管理游标,因为它已被弃用。

用新的 cursorLoader 替代 startManagingCursor 似乎有点矫枉过正。

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

使任务成为 Activity 的内部类并在 Activity 的 onDestroy 方法中关闭光标有时有效,但并非始终有效。

使任务成为 Activity 的内部类并在 Activity 的 onStop 方法中关闭光标似乎可以正常工作。

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

【讨论】:

cursorLoader 太过分了,为什么他们把更多的工作倾倒在你身上而不是倾倒在他们身上【参考方案9】:

startManagingCursor(光标);

这解决了我的问题

【讨论】:

以上是关于完成未停用或关闭的游标非致命错误的主要内容,如果未能解决你的问题,请参考以下文章

打开CAD出现致命错误:安全系统(保密锁或网络许可)不起作用或未正确安装

PHP PDO:致命错误:未捕获的错误:在第[duplicate]行上对bool成员函数execute()的调用

致命错误:未捕获的 PDOException:SQLSTATE[42000] 语法错误或访问冲突

致命错误:未捕获的异常“PDOException”,带有消息“SQLSTATE [42000]:语法错误或访问冲突 PHP 和 PDO

PHP 致命错误:未捕获的 PDOException:SQLSTATE [42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误

OMRON CP系列PLC非致命错误009B