结束未被停用或关闭的非致命错误的游标

时间:2021-02-18 19:39:35

i'm getting a "Finalizing a Cursor that has not been deactivated or closed" error on this piece of code. The code is used to fill a listview.

在这段代码上,我将得到一个“未被禁用或关闭的游标的最终化”错误。代码用于填充listview。

Since it's a non-fatal error , there is no crash and all seems to works fine..but i don't like the error.

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

If i close the cursor at the end of this code..the listview stay's empty. if i close the cursor in onStop , i get the same error.

如果我在这段代码的末尾关闭光标。listview呆是空的。如果我在onStop中关闭光标,就会得到相同的错误。

How do i fix this??

我怎么修复这个?

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 个解决方案

#1


27  

You should not be getting that message if you close the Cursor in onStop() or onDestroy(). Please try that again. Or, call startManagingCursor() after you get the Cursor from your query, and Android will close the Cursor on its own.

如果您关闭onStop()或onDestroy()中的游标,则不应该获得该消息。请再试一次。或者,在从查询中获取游标后调用startManagingCursor(), Android将自动关闭游标。

#2


13  

Scott,

斯科特,

I ran into the same problem as you. Before you close your database, i.e. "db.close()," make sure that your cursors are closed first, i.e. "mCursor.close()"

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

Like so:

像这样:

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(); 
} 

You mentioned that if you closed your cursor your list view stays empty. I recommend you pass the information over to a class and copy it over (allocate the memory) then close the cursor.

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

#3


2  

When a query returns a cursor it is actually positioned "before" the first record in the cursor. An adapter will attempt do a 'getItem' at the first element so it will fail as the cursor is not positioned at any.

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

In my base adapters I do a cursorMoveToPosition on the getViews. This seems to eliminate the need for the movefirst.

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

#4


1  

Do not use startManagingCursor() since that is no longer the recommended approach. The issue occurs because a cursor / DB connection is still not closed by the time the finalizer gets to this object. You can avoid that by either allowing a loader to manage the cursor or by tracking all cursor / DB / SQLiteOpenHelper connections yourself and cleaning up after them.

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

Using a Loader is fairly cumbersome and requires a lot of moving parts for it to work in conjunction with say a list view. On the other hand tracking your cursor and database connections is prone to human error. If the number of cursor / DB objects is low, I'd recommend the latter solution. If not, let a loader handle your connections.

使用加载程序是相当麻烦的,并且需要大量的移动部件使其与列表视图协同工作。另一方面,跟踪游标和数据库连接容易出现人为错误。如果游标/ DB对象的数量较低,我建议采用后一种解决方案。如果没有,让加载程序处理您的连接。

#5


1  

Close the cursor object wherever you are creating it.

在创建游标对象的任何地方关闭游标对象。

When you create a cursor object and done with traversing through a SQLite table then close it after it has been used. This closing of cursor prevents exception in logcat.

当您创建游标对象并遍历一个SQLite表时,在使用它之后关闭它。关闭光标可以防止logcat中的异常。

You will not get any exception related to finalizing the cursor that left opened.

您将不会得到任何与结束左打开的游标相关的异常。

This fixed same issue in my Application.

这个问题在我的申请中也是一样。

#6


0  

I struggled with this problem for two days. I was trying to get sample code working which passed a cursor, returned from a database query, directly to List Adapter - no interim adapter. It refused to work - just displayed a blank screen - until I invoked 'moveToFirst()' on the cursor before passing it to the ListAdapter. Go figure! When I comment this out, it breaks.

我为这个问题挣扎了两天。我试图让示例代码工作,它传递了一个游标,从数据库查询返回,直接列出适配器——没有临时适配器。它拒绝工作——只是显示了一个空白屏幕——直到我在光标上调用了“moveToFirst()”,然后将它传递给ListAdapter。去图!当我把它注释掉的时候,它就坏了。

Just thought that I'd share this to save people the same struggles that I had.

我只是想和大家分享我的经历来拯救那些和我一样挣扎的人。

If anyone can shed some light on why this is so, I'd appreciate it. I haven't had to invoke moveToFirst on cursors up to now, to get them to perform properly.

如果有人能解释为什么会这样,我会很感激的。到目前为止,我还不需要在游标上调用moveToFirst来让它们正常运行。

#7


0  

Just had the same problem and thought to let you know - just in case....

有同样的问题,想让你知道,以防....

I accidentally called my fetch routine two times and hereby "lost" the resulting cursor of the first call. This caused the error.

我两次不小心调用了我的fetch例程,并在此“丢失”了第一个调用的结果游标。这造成了错误。

#8


0  

I too have been having issues with the closing the cursor:

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

  • Closing the cursor right after setting the list view's adapter causes the cursor to close before the data gets displayed.

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

  • Can't use startManagingCursor to manage the cursor because it has been deprecated.

    不能使用startManagingCursor管理游标,因为它已经被废弃了。

  • The new cursorLoader replacement for startManagingCursor seems to be overkill.

    替换startManagingCursor的新cursorLoader似乎有些过份了。

  • Moving the cursor's position as suggested did not work.

    按照建议移动光标的位置是无效的。

  • Making the task an inner class of the activity and closing the cursor in the activity's onDestroy method works sometimes but not all the time.

    将任务设置为活动的内部类,并在活动的onDestroy方法中关闭光标,有时会有效,但并非总是如此。

  • Making the task an inner class of the activity and closing the cursor in the activity's onStop method seems to be working.

    将任务设置为活动的内部类,并在活动的onStop方法中关闭光标,这似乎是有效的。

I also found out that I can close the database and the sqlite open helper before closing the cursor. I can even close them right after setting the list view's adapter. The data will still display.

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

#9


0  

startManagingCursor(cursor);

startManagingCursor(光标);

This has fixed my problem

这解决了我的问题

#1


27  

You should not be getting that message if you close the Cursor in onStop() or onDestroy(). Please try that again. Or, call startManagingCursor() after you get the Cursor from your query, and Android will close the Cursor on its own.

如果您关闭onStop()或onDestroy()中的游标,则不应该获得该消息。请再试一次。或者,在从查询中获取游标后调用startManagingCursor(), Android将自动关闭游标。

#2


13  

Scott,

斯科特,

I ran into the same problem as you. Before you close your database, i.e. "db.close()," make sure that your cursors are closed first, i.e. "mCursor.close()"

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

Like so:

像这样:

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(); 
} 

You mentioned that if you closed your cursor your list view stays empty. I recommend you pass the information over to a class and copy it over (allocate the memory) then close the cursor.

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

#3


2  

When a query returns a cursor it is actually positioned "before" the first record in the cursor. An adapter will attempt do a 'getItem' at the first element so it will fail as the cursor is not positioned at any.

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

In my base adapters I do a cursorMoveToPosition on the getViews. This seems to eliminate the need for the movefirst.

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

#4


1  

Do not use startManagingCursor() since that is no longer the recommended approach. The issue occurs because a cursor / DB connection is still not closed by the time the finalizer gets to this object. You can avoid that by either allowing a loader to manage the cursor or by tracking all cursor / DB / SQLiteOpenHelper connections yourself and cleaning up after them.

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

Using a Loader is fairly cumbersome and requires a lot of moving parts for it to work in conjunction with say a list view. On the other hand tracking your cursor and database connections is prone to human error. If the number of cursor / DB objects is low, I'd recommend the latter solution. If not, let a loader handle your connections.

使用加载程序是相当麻烦的,并且需要大量的移动部件使其与列表视图协同工作。另一方面,跟踪游标和数据库连接容易出现人为错误。如果游标/ DB对象的数量较低,我建议采用后一种解决方案。如果没有,让加载程序处理您的连接。

#5


1  

Close the cursor object wherever you are creating it.

在创建游标对象的任何地方关闭游标对象。

When you create a cursor object and done with traversing through a SQLite table then close it after it has been used. This closing of cursor prevents exception in logcat.

当您创建游标对象并遍历一个SQLite表时,在使用它之后关闭它。关闭光标可以防止logcat中的异常。

You will not get any exception related to finalizing the cursor that left opened.

您将不会得到任何与结束左打开的游标相关的异常。

This fixed same issue in my Application.

这个问题在我的申请中也是一样。

#6


0  

I struggled with this problem for two days. I was trying to get sample code working which passed a cursor, returned from a database query, directly to List Adapter - no interim adapter. It refused to work - just displayed a blank screen - until I invoked 'moveToFirst()' on the cursor before passing it to the ListAdapter. Go figure! When I comment this out, it breaks.

我为这个问题挣扎了两天。我试图让示例代码工作,它传递了一个游标,从数据库查询返回,直接列出适配器——没有临时适配器。它拒绝工作——只是显示了一个空白屏幕——直到我在光标上调用了“moveToFirst()”,然后将它传递给ListAdapter。去图!当我把它注释掉的时候,它就坏了。

Just thought that I'd share this to save people the same struggles that I had.

我只是想和大家分享我的经历来拯救那些和我一样挣扎的人。

If anyone can shed some light on why this is so, I'd appreciate it. I haven't had to invoke moveToFirst on cursors up to now, to get them to perform properly.

如果有人能解释为什么会这样,我会很感激的。到目前为止,我还不需要在游标上调用moveToFirst来让它们正常运行。

#7


0  

Just had the same problem and thought to let you know - just in case....

有同样的问题,想让你知道,以防....

I accidentally called my fetch routine two times and hereby "lost" the resulting cursor of the first call. This caused the error.

我两次不小心调用了我的fetch例程,并在此“丢失”了第一个调用的结果游标。这造成了错误。

#8


0  

I too have been having issues with the closing the cursor:

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

  • Closing the cursor right after setting the list view's adapter causes the cursor to close before the data gets displayed.

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

  • Can't use startManagingCursor to manage the cursor because it has been deprecated.

    不能使用startManagingCursor管理游标,因为它已经被废弃了。

  • The new cursorLoader replacement for startManagingCursor seems to be overkill.

    替换startManagingCursor的新cursorLoader似乎有些过份了。

  • Moving the cursor's position as suggested did not work.

    按照建议移动光标的位置是无效的。

  • Making the task an inner class of the activity and closing the cursor in the activity's onDestroy method works sometimes but not all the time.

    将任务设置为活动的内部类,并在活动的onDestroy方法中关闭光标,有时会有效,但并非总是如此。

  • Making the task an inner class of the activity and closing the cursor in the activity's onStop method seems to be working.

    将任务设置为活动的内部类,并在活动的onStop方法中关闭光标,这似乎是有效的。

I also found out that I can close the database and the sqlite open helper before closing the cursor. I can even close them right after setting the list view's adapter. The data will still display.

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

#9


0  

startManagingCursor(cursor);

startManagingCursor(光标);

This has fixed my problem

这解决了我的问题