Получение java.lang.IllegalStateException: попытка повторно открыть уже закрытый объект: при использовании курсора в Android - PullRequest
1 голос
/ 21 декабря 2011

Я использую Курсор для получения данных из БД (это информация о маркерах наложения на карте).Я загружаю карту с помощью этих данных.Взаимодействие с БД через Курсор осуществляется в 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 ();"

1 Ответ

1 голос
/ 21 декабря 2011

Поскольку вы вручную закрываете курсор с помощью cursor.close(), вы не должны вызывать startManagingCursor(cursor). Вам нужно выбрать один или другой.

Поскольку вы делаете это в AsyncTask, вы почти наверняка не хотите, чтобы включающий Activity управлял курсором вместо вас, поскольку AsyncTask может пережить Activity. Так что просто сделай это вручную.

(Полагаю, AsyncTask - это внутренний класс вашего Activity.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...