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(SQLiteDirectCursorDriver.java:
53)
E/Cursor ( 2318): at
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:
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
这解决了我的问题