【问题标题】:How to resolve "Trying to reopen a closed SQLite database" in android如何在android中解决“尝试重新打开关闭的SQLite数据库”
【发布时间】:2021-02-21 19:29:01
【问题描述】:

我一直在构建一个使用 SQLiteOpenHelper 来管理 SQLite 数据库的 Android 应用程序。应用程序 SQLite 的数据库工作正常,我似乎可以找到任何错误,我检查了我在每个 SQLite 数据库操作上调用了new SQLiteOpenHelper().close() 以防止数据泄漏。但是几个月后,我收到一条错误消息,告诉我我正在尝试重新打开一个已经关闭的 SQLite 数据库。但是我仔细检查了所有内容,似乎找不到任何问题。我很困惑可能是什么问题。任何帮助表示赞赏。提前致谢。

编辑

这是产生错误的代码。 Android studio 在 where 行报错;

Cursor result = db.rawQuery(selectStmt, null) 存在。

public List<DataModel> getAssignmentData() {

        List<DataModel> data = new ArrayList<>();
        SQLiteDatabase db = getReadableDatabase();
        String selectStmt
                = "SELECT " + COLUMN_ASSIGNMENT_TITLE + ", "
                + COLUMN_SUBMISSION_DATE + ", "
                + COLUMN_ASSIGNMENT_DESCRIPTION + ", "
                + COLUMN_LECTURER_NAME + ", "
                + COLUMN_COURSE_CODE + ", "
                + COLUMN_ATTACHED_IMAGE + ", "
                + COLUMN_ID + ", "
                + COLUMN_SUBMITTED + " FROM " + ASSIGNMENT_TABLE;

        Cursor result = db.rawQuery(selectStmt, null);

        if (result.moveToFirst()) {
            do {
                String title = result.getString(0);
                String date = result.getString(1);
                String description = result.getString(2);
                String lecturerName = result.getString(3);
                String course = result.getString(4);
                String attachedImages = result.getString(5);
                int id = result.getInt(6);
                boolean submitted = result.getInt(7) == 1;

                AssignmentModel assignment = new AssignmentModel();
                assignment.setTitle(retrieveEntry(title));
                assignment.setDate(date);
                assignment.setDescription(retrieveEntry(description));
                assignment.setLecturerName(retrieveEntry(lecturerName));
                assignment.setCourseCode(course);
                assignment.setAttachedImage(attachedImages);
                assignment.setPosition(id);
                assignment.setSubmitted(submitted);

                data.add(assignment);
            } while (result.moveToNext());

        }
        result.close();
        return data;
    }

【问题讨论】:

    标签: java android database sqlite


    【解决方案1】:

    Android SQLiteDatabase 内部有一个简单的引用计数。 new SQLiteOpenHelper() 构造函数调用不会打开数据库,即增加引用计数,但调用 close() 会减少它,可能会使您因其他原因打开的 SQLiteDatabase 引用无效。

    不要将close() 与构造函数调用配对,而是将它们与数据库的实际打开配对,例如getWritableDatabase()getReadableDatabase()。如果您发布更多代码,我们可以为您提供更好的帮助。

    【讨论】:

    • 代码很大,我不知道该发布什么。我实际上并没有在 SQLiteOpenHelper 类上调用 close(),而是从一个子类 SchoolDatabase 调用 close()。所以你说的是我应该为每个 getWritableDatabase() 或 getReadableDatabase() 调用调用 close,即在使用它执行 SQLite 操作之后。
    • 重现您的问题的最小化将是理想的。无论如何,请确保您仅在实际打开某些内容时才调用close()
    • 这正是我要说的。当我使用 SQLiteOpenHelper 时,我正确关闭了它,一切正常,但使用该应用程序几个月后,它崩溃并报告我试图打开一个已经关闭的数据库
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多