获取 java.lang.IllegalStateException:尝试重新打开已关闭的对象:在 Android 中使用光标时
我正在使用 Cursor 从数据库获取数据(它是有关地图上叠加标记的信息)。我正在借助这些数据加载地图。通过 Cursor 与数据库的交互是在 asyncTask 中完成的。
现在这是我面临的问题。如果我在光标运行时按后退按钮来加载地图(即在 while 循环中加载覆盖标记的中间),我会收到此错误:
Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, category, latitude, longitude FROM node)
这是它的完整跟踪:
12-21 11:11:30.173: E/AndroidRuntime(2824): FATAL EXCEPTION: AsyncTask #5
12-21 11:11:30.173: E/AndroidRuntime(2824): java.lang.RuntimeException: An error occured while executing doInBackground()
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.os.AsyncTask$3.done(AsyncTask.java:200)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.lang.Thread.run(Thread.java:1102)
12-21 11:11:30.173: E/AndroidRuntime(2824): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, category, latitude, longitude FROM node)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:34)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:64)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:299)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:271)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:188)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.AbstractCursor.moveToNext(AbstractCursor.java:256)
12-21 11:11:30.173: E/AndroidRuntime(2824): at org.mid.kew.activities.MapPageActivity$MapLoadingAsyncTask.doInBackground(MapPageActivity.java:632)
12-21 11:11:30.173: E/AndroidRuntime(2824): at org.mid.kew.activities.MapPageActivity$MapLoadingAsyncTask.doInBackground(MapPageActivity.java:1)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.os.AsyncTask$2.call(AsyncTask.java:185)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-21 11:11:30.173: E/AndroidRuntime(2824): ... 4 more
这是我正在使用的代码的快照在 asyncTask 中的
DoInBackground 方法下的
openKewDataBase();
Cursor cursor = getCursorForOverLayIcons();
startManagingCursor(cursor);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
...
cursor.moveToNext();
}
cursor.close();
onPostExecute 方法下,
....
closeKewDataBase();
我可以跟踪它在“cursor.moveToNext();”处的崩溃
I am using Cursor to get data from DB (it's information about the overlay markers on Map). I am loading a map with help of this data. Interaction with the DB through Cursor is done in a asyncTask.
Now here is the problem I am facing. If I press back button while the cursor is running to load the map (i.e. in middle of loading overlay markers in a while loop) I get this error:
Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, category, latitude, longitude FROM node)
Here is the complete trace of it:
12-21 11:11:30.173: E/AndroidRuntime(2824): FATAL EXCEPTION: AsyncTask #5
12-21 11:11:30.173: E/AndroidRuntime(2824): java.lang.RuntimeException: An error occured while executing doInBackground()
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.os.AsyncTask$3.done(AsyncTask.java:200)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.lang.Thread.run(Thread.java:1102)
12-21 11:11:30.173: E/AndroidRuntime(2824): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, category, latitude, longitude FROM node)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:34)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:64)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:299)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:271)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:188)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.database.AbstractCursor.moveToNext(AbstractCursor.java:256)
12-21 11:11:30.173: E/AndroidRuntime(2824): at org.mid.kew.activities.MapPageActivity$MapLoadingAsyncTask.doInBackground(MapPageActivity.java:632)
12-21 11:11:30.173: E/AndroidRuntime(2824): at org.mid.kew.activities.MapPageActivity$MapLoadingAsyncTask.doInBackground(MapPageActivity.java:1)
12-21 11:11:30.173: E/AndroidRuntime(2824): at android.os.AsyncTask$2.call(AsyncTask.java:185)
12-21 11:11:30.173: E/AndroidRuntime(2824): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-21 11:11:30.173: E/AndroidRuntime(2824): ... 4 more
and here is a snapshot of code I am using in asyncTask
Under DoInBackground method
openKewDataBase();
Cursor cursor = getCursorForOverLayIcons();
startManagingCursor(cursor);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
...
cursor.moveToNext();
}
cursor.close();
Under onPostExecute Method
....
closeKewDataBase();
As per I can trace Its crashing at "cursor.moveToNext();"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您使用
cursor.close()
手动关闭光标时,不应调用startManagingCursor(cursor)
。您需要选择其中之一。当您在
AsyncTask
中执行此操作时,您几乎肯定不希望封闭的Activity
为您管理光标,因为AsyncTask
可以比Activity
更长久。所以只需手动执行即可。(我假设
AsyncTask
是您的Activity
的内部类。)As you are manually closing the cursor with
cursor.close()
, you shouldn't callstartManagingCursor(cursor)
. You need to choose one or the other.As you are doing this in an
AsyncTask
, you almost certainly don't want the enclosingActivity
to manage the cursor for you, as theAsyncTask
can outlive theActivity
. So just do it manually.(I presume the
AsyncTask
is an inner class of yourActivity
.)