IllegalStateException:база данных уже закрыта (с помощью ViewPager)
Вопрос
Я не понимаю, что вызывает эту ошибку, поскольку я убедился, что правильно закрываю адаптер базы данных (по крайней мере, я так думаю).Вот что говорит LogCat (все они имеют тег AndroidRuntime):
ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ:Главный java.lang.illegalstateException:База данных /дата/data/com.acedit.assignamo/databases/data.db (conn# 0) уже закрыта на android.database.sqlite.sqlitedatabase.verifydbisopen (sqlitedatabase.java:2082) atroid.database.sqlite.sqlitabase. lock (sqlitedatabase.java:413) at android.database.sqlite.sqlitedatabase.lock (sqlitedatabase.java:400) at android.database.sqlite.sqlitequery.fillwindow (sqlitequery.java:79) atride.daTabase.StaBase.SqlIndow (sqliteQuery.java:79) atride.dasbase.dabasebase. .fillWindow (sqliteCursor.java:164) at android.database.sqlite.sqlitecursor.onmove (sqlitecursor.java:147) at android.database.abstractcursor.movetoposition (Abstractcursor.java:178). CursorAdapter.getIteMID (custorAdapter.java:225) на android.widget.abslistview.onsaveinstancestate (abslistview.java:1569) at android.view.view.dispatchsaveinstancestate (view.java:9868) android. .java: 2310) at android.widget.adapterView.dispatchSaveInstanceState (adapterView.java:770) at android.view.viewgroup.dispatchsaveinstancestate (viewgroup.java:2296) at android.view.view.savehierarry (view.java:2296) at android.view.view.savehierarchystate (java:2296). at android.support.v4.app.pragmentmanagerimpl.savefragmentViewState (FragmentManager.java:1561) at android.support.v4.app.pragmentmanagermpl.movetostate (fragmentmanager.java:962) at android.support.v4.app.fragmentmanagemplimplimplimplimplimplimplimplimplimprimplimplimprimplimprimprimplimprimplimprimplamprimprimprimprimprimprimprimprimprimprimprimprimprimprimprimprimprimpl (FragmentManager.java:1233) at android.support.v4.app.backstackRecord.run (BackstackRecord.java:620) на Android.support.v4.app.app.fragmentmanagerimpl.execpendionsCations (fragmentManager.java:1431) android.support. v4.app.fragmentmanagerimpl.executependingTransactions (fragmentManager.java:431) на android.support.v4.app.fragmentpageradapter.finishupdate (FragmentPagerAdapter.java:141) at android.support.v4.view.viewpage. 895) at android.support.v4.view.viewpager.populate (viewpager.java:772) at android.support.v4.view.viewpager.completescroll (viewpager.java:1539) at android.support.v4.view.viewpager .computescroll (viewpager.java:1422) at android.view.view.getDisplaylist (view.java:10406) at android.view.viewgroup.dispatchgetDisplaylist (viewGroup.java:2597) at android.view.view.getdisplaylist (viele. Java: 10380) at android.view.viewgroup.dispatchgetdisplaylist (viewgroup.java:2597) at android.view.view.getdisplaylist (view.java:10380) at android.view.viewgroup.dispatchgetlist (viewgroup.java:2597) Android.view.view.getDisplayList (view.java:10380) at android.view.viewgroup.dispatchgetdisplaylist (viewgroup.java:2597) на android.view.view.getdisplaylist (view.java:10380) aterroid.view.hardwarerender $ Glrenderer.draw (hardwarerenderer.java:875) at android.view.viewRootimpl.draw (viewRootimpl.java:1910) at android.view.viewRootimpl.performTraversals (viewRootimpl.java:1634) android.view.viewryshple (viewrootimpl.java:1634) ayroid.view.viewryspryprypryprypravers. ViewRootimpl.java:2442) at android.os.handler.dispatchmessage (handler.java:99) на android.os.looper.loop (looper.java:137) at android.app.activitythread.main (Activitythread.java:4575 ) на java.lang.reflect.method.invokenative (нативном методе) на java.lang.reflect.method.invoke (method.java:511) на com.android.os.os.zygoteinit $ methodandargscaller.run (zygoteinit.java : 786) на com.android.internal.os.zygoteinit.main (zygoteinit.java:553) на dalvik.system.nativestart.main (нативный метод)
Мой код:
public Cursor fetchIncompleteAssignments(Short course) {
DbAdapter adapter = new DbAdapter(context, null, Values.ASSIGNMENT_TABLE);
adapter.open();
Cursor r;
if (course == null) // Fetching from all courses
r = adapter.fetchAllWhere(Values.ASSIGNMENT_LIST_FETCH, Values.ASSIGNMENT_KEY_STATUS + "=" + 0, Values.ASSIGNMENT_KEY_DUE_DATE);
else
r = adapter.fetchAllWhere(Values.ASSIGNMENT_LIST_FETCH, Values.ASSIGNMENT_KEY_COURSE + "=" + course
+ " AND " + Values.ASSIGNMENT_KEY_STATUS + "=" + 0, Values.ASSIGNMENT_KEY_DUE_DATE);
adapter.close();
return r;
}
// Part of DbAdapter:
public DbAdapter open() throws SQLException {
dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
public void close() {
if (db != null) {
try {
db.close();
dbHelper.close();
} catch (NullPointerException e) {
Log.e("Close", "Error: " + e + " " + e.getMessage());
}
} else
Log.e("Close", "Error! db \"" + DATABASE_TABLE + "\" is null.");
}
А Cursor
вернулся из fetchAllAssignments()
используется для заполнения ListView
через обычай CursorAdapter
.А ListView
это содержание ListFragment
, и на каждой странице ViewPager отображается несколько экземпляров этого ListFragment (один для отображения заданий из всех курсов, а затем страница для каждого отдельного курса).
Есть идеи, что не так?Насколько я знаю, я правильно закрываю свою базу данных.Дайте мне знать, если вам нужно больше кода.Заранее спасибо!
РЕДАКТИРОВАТЬ: Данные извлекаются из базы данных нормально и также заполняют ListView.Я могу пролистывать различные страницы, но, похоже, происходит сбой всякий раз, когда фрагмент останавливается.Когда я запускаю другое действие, он часто выходит из строя, но не всегда.Он также иногда вылетает, когда я пролистываю страницы, хотя и очень редко.Вот мой метод onPause() для моего фрагмента (у меня нет onStop() или onDestroy()):
public void onPause() {
super.onPause();
if (!assignmentsCursor.isClosed()) {
assignmentsCursor.close();
assignmentsCursor = null;
}
}
В моем onResume()
Я просто перезагружаю список из базы данных и получаю новую копию контекста через getActivity()
.Возможно, что-то очищается (для памяти), и я не перезагружаю?Я не получаю никаких исключений NullPointerException, поэтому мне это кажется маловероятным...
Решение
на самом деле это исключение возникает потому, что вы дважды закрываете свою базу данных, а не потому, что вы ее не закрыли.
так..
в тебе close()
метод, замените следующую строку в своем коде:
if (db != null) {
с:
if (db != null && db.isOpen()) {
Другие советы
Сделайте свой DbHelper
синглтон, как описано в эта почта.