2

我经常从用户那里收到有关此错误的报告。

无法获取可写数据库。

try {
        //dbOpenHelper is a standard SQLiteOpenHelper
        dbOpenHelper.getWritableDatabase();             
} catch (Exception e) {
        //unable to connect to database.
        return;
}

这只是偶尔发生。会是什么呢?任何修复或解决方法?

4

2 回答 2

0

尝试 getReadableDatabase() 而不是 getWritableDatabase()

try {
        //dbOpenHelper is a standard SQLiteOpenHelper
        dbOpenHelper.getReadableDatabase();           
} catch (Exception e) {
        //unable to connect to database.
        return;
}
于 2012-10-25T20:11:17.743 回答
0

没什么可做的,需要查看您的 LogCat 以进一步提供帮助。你要关闭你的dbOpenHelper吗?

这是一个简单的例子:

public DatabaseControl open() throws SQLiteException {
    dbHelper = new DatabaseHelper(context);
    database = dbHelper.getWritableDatabase();
    return this;
}

public void close() {
    dbHelper.close();
}

编辑 1 - 同样,这是我最好的猜测,因为无法获得 LogCat。(最后,在您的开发设备上运行此应用程序并尝试复制然后获取完整的 LogCat 输出可能符合您的最大利益)

在我看来,拥有数据库的 Activity 正在被正确地访问和处理close(),但在某些情况下,用户可能没有通过该 Activity 运行,而是按下后退按钮,onBackPressed()可能应该有一个 DBclose()调用?

换句话说,为了排除故障,我会@Override使用 Acitivity 生命周期方法:onPause()onResume()onStart()onStop()onDestroy()以及onBackPressed()简单地添加数据库close()并测试您的应用程序。如果你这样做,我会认为,任何返回的生命周期,例如onStart()onResume()应该包含数据库getWritableDatabase()

根据文档(见下文),Unable to getWritableDatabase除非数据库未正确关闭,否则确实无法获取。还要确保如果您更改 SQlite 代码/结构中的任何内容,您需要更新 DB 版本号。

公共 SQLiteDatabase getWritableDatabase ()

创建和/或打开将用于读取和写入的数据库。第一次调用时,将打开数据库并调用 onCreate(SQLiteDatabase)、onUpgrade(SQLiteDatabase, int, int) 和/或 onOpen(SQLiteDatabase)。

一旦打开成功,数据库就会被缓存,所以每次需要写入数据库时​​都可以调用该方法。(确保在不再需要数据库时调用 close()。)权限错误或磁盘已满等错误可能会导致此方法失败,但如果问题得到解决,以后的尝试可能会成功。


编辑 2

我应该在第一次展示我是如何调用open()andclose()方法的。对于那个很抱歉。除非您正在检索或发布到它,否则您不需要DatabaseHelper打开它,因此在处理后立即关闭它,直到您下次需要它。Cursor等也一样

下面是我如何查询数据库,打开所有内容,检索信息,处理信息,然后立即关闭所有内容。见下文:

DatabaseControl control = new DatabaseControl(this);

try {
    database = (new DatabaseHelper(this)).getWritableDatabase();
    DatabaseControl control = new DatabaseControl(DbTestDisplay.this);
    control.open();
    control.fetchAllItems();
    Cursor c = database.query(GlobalDBVars.TABLE_NAME, null, null, null, null, null, null, null);
    c.moveToFirst();

    int initialCount = c.getCount();
    Log.i("cursor", "Initial Count = " + initialCount);

    List<Integer> x = new ArrayList<Integer>();
    if (initialCount > 0) {
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {

            /* Process everything here */

        } /* End for loop */ 
    } /* End if statement */
    control.close();
    c.close();
    database.close();
} catch (SQLException sqe) {
    Log.e("fetchAllItems", "FAILED: " + sqe.getMessage() + " allData = ");
}
于 2012-10-19T20:17:05.753 回答