Android 最终确定尚未停用或关闭的非致命错误的 Cursor
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3068320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Finalizing a Cursor that has not been deactivated or closed non-fatal error
提问by arnold
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.
我在这段代码中收到“完成尚未停用或关闭的光标”错误。该代码用于填充列表视图。
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)
....
....
采纳答案by CommonsWare
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.
如果关闭Cursor
inonStop()
或,则不应收到该消息onDestroy()
。请再试一次。或者,startManagingCursor()
在您Cursor
从查询中获取 后调用,Android 将Cursor
自行关闭。
回答by jbaez
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.
您提到如果关闭光标,您的列表视图将保持为空。我建议您将信息传递给一个类并复制它(分配内存)然后关闭游标。
回答by Dent
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 上执行了 cursorMoveToPosition。这似乎消除了对 movefirst 的需要。
回答by Deepak Bala
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/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.
使用 Loader 相当麻烦,需要很多活动部件才能与列表视图结合使用。另一方面,跟踪光标和数据库连接很容易出现人为错误。如果游标/数据库对象的数量很少,我会推荐后一种解决方案。如果没有,让加载程序处理您的连接。
回答by Master
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.
这在我的应用程序中修复了相同的问题。
回答by user387184
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 例程两次,因此“丢失”了第一次调用的结果游标。这导致了错误。
回答by subduedjoy
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.
The new cursorLoader replacement for startManagingCursor seems to be overkill.
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.
Making the task an inner class of the activity and closing the cursor in the activity's onStop method seems to be working.
在设置列表视图的适配器后立即关闭光标会导致在显示数据之前关闭光标。
不能使用 startManagingCursor 来管理游标,因为它已被弃用。
startManagingCursor 的新 cursorLoader 替代品似乎有点矫枉过正。
按照建议移动光标的位置不起作用。
使任务成为活动的内部类并在活动的 onDestroy 方法中关闭光标有时有效,但并非总是如此。
使任务成为活动的内部类并在活动的 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。我什至可以在设置列表视图的适配器后立即关闭它们。数据仍将显示。
回答by Krishna
startManagingCursor(cursor);
开始管理光标(光标);
This has fixed my problem
这解决了我的问题
回答by birdman
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.
我在这个问题上挣扎了两天。我试图让示例代码工作,它将从数据库查询返回的游标直接传递给列表适配器 - 没有临时适配器。它拒绝工作——只是显示一个空白屏幕——直到我在将光标传递给 ListAdapter 之前调用了光标上的“moveToFirst()”。去搞清楚!当我评论这个时,它打破了。
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 来让它们正常执行。