Android SQLite SQLiteOpenHelper IllegalStateException - ошибка БД уже закрыта - PullRequest
11 голосов
/ 30 июня 2011

Это сводит меня с ума уже несколько дней.У меня есть приложение для Android, которое довольно сложное.Он использует несколько потоков для извлечения данных с сервера и заполнения базы данных SQLite.Я использую синглтон для ссылки на мое расширение SQLiteOpenHelper.Я открываю и закрываю базу данных в каждой из моих операций.

Ошибка возникает ТОЛЬКО в ситуации, когда у меня 4 глубоких действия и затем я пытаюсь вернуться назад.Я пробовал различные способы открытия и закрытия базы данных, включая перемещение закрытия из onDestroy () в методы onPause (), а также добавление еще одного открытия в onResume ().

Также обратите внимание, мойдействия интенсивно используют ListViews и ExpandableListViews, которые, как я понимаю, могут привести к закрытию базы данных на основе этой статьи: http://darutk -oboegaki.blogspot.com / 2011/03 / sqlitedatabase-is-closed-automatic.html

Я просмотрел код и убедился, что я либо закрываю все свои курсоры, либо, если они назначаются адаптеру, вызывает функцию startManagingCursor ().

Кто-нибудь знает, что происходит?

java.lang.RuntimeException: Unable to resume activity {com.fieldone/com.fieldone.DispatchActivity}: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3347)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3362)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2162)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:144)
    at android.app.ActivityThread.main(ActivityThread.java:4937)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed
    at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:237)
    at android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:145)
    at android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:567)
    at android.app.Activity.performRestart(Activity.java:3836)
    at android.app.Activity.performResume(Activity.java:3857)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3337)
    ... 10 more

ОБНОВЛЕНИЕ: Я исправил проблему, но не уверен, ПОЧЕМУ это решило ее.Так что, может быть, кто-то там знает или мог бы объяснить.

Когда я нахожусь в четвертом действии стека действий, я пытался закрыть базу данных с помощью db.close ().Неважно, ГДЕ я поместил это, в onCreate после получения нужных мне данных, или в onStop или onDestroy, это приведет к этой ошибке.Если я НЕ закрываю БД, у меня нет проблемы.Итак, что-то вызывает автоматическое закрытие БД.Странно то, что хотя в этом последнем упражнении я использую expandableListView, я НЕ использую курсор Адаптер.У кого-нибудь есть мысли?Хотелось бы понять это.

Ответы [ 3 ]

20 голосов
/ 27 октября 2011

Поскольку этот вопрос привлек много внимания, я хотел ответить на него и описать то, что я узнал и что помогло мне исправить эту проблему в моем большом приложении на основе базы данных:

  1. НЕ используйте управляемые курсоры. Есть причина, почему они устарели. Они абсолютно проблематичны. В действительности, существует очень мало сценариев, когда вам все равно нужно использовать управляемый курсор. Вместо этого запустите ваш запрос и заполните объект результатами. Если вы запрашиваете несколько строк, создайте ArrayList <> вашего объекта для хранения всех строк. Теперь я создаю функцию, которая выполняет запрос и передает мне мой ArrayList <>, а не курсор в возвращаемом файле. Я закрываю курсор внутри функции и все готово. Для ListViews вы больше не сможете использовать SimpleCursorAdapter. Просто преобразуйте все это в BaseAdapter и используйте объект ArrayList <> для его заполнения.

  2. НЕ ЗАБУДЬТЕ ЗАКРЫТЬ ВСЕ КУРСОРЫ. Это также может нанести ущерб соединениям БД вашего приложения. Я думал, что делаю это, но, конечно же, нашел место, где я явно не закрывал курсор. Итак, просмотрите ваше приложение и дважды проверьте их все.

Я также использую одноэлементный объект DatabaseHelper. Я объявляю статический объект DatabaseHelper в своем классе SQLiteOpenHelper, чтобы каждый раз получать один и тот же экземпляр.

Теперь у меня есть стабильно работающее приложение, которое больше не получает эти ошибки БД. Я надеюсь, что эта информация полезна для некоторых из вас.

2 голосов
/ 17 августа 2011

использовать CursorAdapter.changeCursor (null), может замедлить появление этой ошибки, но не может полностью решить проблему, неизвестный период времени появится снова. Это тоже сводит меня с ума!

1 голос
/ 10 апреля 2012

У меня также была та же проблема 'БД уже закрытое исключение с недопустимым оператором курсора в fillWindow () и IllegalStatementException'.Я установил курсор (w / c также из SimpleCursorAdapter) в переменную экземпляра, а не в переменную метода, а затем в методы onStop и onPause, затем вызываю stopManagingCursor, а затем в методах onResume и onStart вызываю startManagingCursor.

Это решило мою проблему для меня, и после этого я не нашел никаких сообщений об ошибках или предупреждений в моем logcat :) Надеюсь, это кому-нибудь тоже поможет.

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