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

时间:2010-06-18 08:56:38

标签: android cursor

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

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

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

9 个答案:

答案 0 :(得分:27)

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

答案 1 :(得分: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(); 
} 

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

答案 2 :(得分:2)

当查询返回游标时,它实际上位于第一个游标之前 记录在光标中。适配器将尝试在第一个执行'getItem' 因为光标没有位于任何元素,它将失败。

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

答案 3 :(得分:1)

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

使用Loader非常麻烦,需要大量的移动部件才能与列表视图一起使用。另一方面,跟踪光标和数据库连接很容易出现人为错误。如果光标/ DB对象的数量很少,我建议使用后一种解决方案。如果没有,让装载机处理你的连接。

答案 4 :(得分:1)

关闭光标对象,无论您在何处创建它。

创建游标对象并遍历SQLite表时,请在使用后关闭它。这种关闭游标可以防止logcat中的异常。

您不会得到任何与最终确定左侧打开的光标相关的异常。

我的应用程序中修复了同样的问题。

答案 5 :(得分:0)

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

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

如果有人能说清楚为什么会这样,我会很感激。到目前为止,我还没有在游标上调用moveToFirst,以使它们正常运行。

答案 6 :(得分:0)

遇到同样的问题,并想让你知道 - 以防万一......

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

答案 7 :(得分:0)

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

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

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

  • startManagingCursor的新cursorLoader替换似乎有点矫枉过正。

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

  • 使任务成为活动的内部类,并在活动的onDestroy方法中关闭游标有时会工作,但不是所有时间。

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

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

答案 8 :(得分:0)

startManagingCursor(光标);

这解决了我的问题