IllegalStateException: database already closed (using ViewPager)

蹲街弑〆低调 提交于 2020-01-02 04:44:09

问题


I'm stumped as to what is causing this error, as I have made sure that I am closing my database adapter properly (at least I think I am). Here's what LogCat's saying (the tag for all of them is AndroidRuntime):

FATAL EXCEPTION: main java.lang.IllegalStateException: database /data/data/com.acedit.assignamo/databases/data.db (conn# 0) already closed at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2082) at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:413) at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:400) at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:79) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:164) at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:147) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:178) at android.support.v4.widget.CursorAdapter.getItemId(CursorAdapter.java:225) at android.widget.AbsListView.onSaveInstanceState(AbsListView.java:1569) at android.view.View.dispatchSaveInstanceState(View.java:9868) at android.view.ViewGroup.dispatchFreezeSelfOnly(ViewGroup.java:2310) at android.widget.AdapterView.dispatchSaveInstanceState(AdapterView.java:770) at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2296) at android.view.View.saveHierarchyState(View.java:9851) at android.support.v4.app.FragmentManagerImpl.saveFragmentViewState(FragmentManager.java:1561) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:962) at android.support.v4.app.FragmentManagerImpl.detachFragment(FragmentManager.java:1233) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:620) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431) at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431) at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) at android.support.v4.view.ViewPager.populate(ViewPager.java: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(View.java:10380) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:875) at android.view.ViewRootImpl.draw(ViewRootImpl.java:1910) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634) at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4575) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method)

My code:

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.");
}

The Cursor returned from fetchAllAssignments() is used to populate a ListView through a custom CursorAdapter. The ListView is the content of a ListFragment, and there are multiple instances of this ListFragment displayed in each page of a ViewPager (one for showing assignments from all courses, and then a page for each of the individual courses).

Any ideas as to what is wrong? As far as I know, I'm closing my database correctly. Let me know if you need more code. Thanks in advance!

EDIT: The data is pulled from the database fine, and it populates the ListView as well. I can swipe through the various pages, but it seems to crash whenever the Fragment is stopped. It will often crash when I start another Activity, but not always. It will also occasionally crash when I'm swiping through the pages, though very rarely. Here's my onPause() method for my Fragment (I don't have an onStop() or onDestroy()):

public void onPause() {
    super.onPause();
    if (!assignmentsCursor.isClosed()) {
        assignmentsCursor.close();
        assignmentsCursor = null;
    }
}

In my onResume() I just reload the list from the database and get a new copy of the context via getActivity(). Perhaps something is getting cleared (for memory purposes) and I'm not reloading it? I'm not getting any kind of NullPointerException, so this seems unlikely to me...


回答1:


this exception actually is raised because you double close your database, not because you did not close it.

so..

in you close() method, replace the following line in your code:

if (db != null) {

with:

if (db != null && db.isOpen()) {



回答2:


Make your DbHelper a singleton, as described in this post.



来源:https://stackoverflow.com/questions/12702254/illegalstateexception-database-already-closed-using-viewpager

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!