【发布时间】:2021-09-01 23:14:13
【问题描述】:
我们一直在设置一个 android 应用程序,但在使用 SQLite 时遇到了一个奇怪的错误,其中相同的查询有时会提供结果,有时不会。
运行以下代码时,它可能会返回请求的行,或者 cursor.moveToFirst 可能会返回 false。导致返回空值。
我一直无法弄清楚为什么cursor.moveToFirst() 可能会失败。代码运行相同的语句,名称在同一个数据库上相同。
奇怪的是,它几乎似乎在给出请求的行和什么都不给出之间交替。
此方法是从 ASyncTask 调用的,因此可能会连续调用多个,但从按钮触发的任务不太可能同时调用两次。
最低 android api 级别为 8
connectionInfo 对象是返回信息的包装器。
connectionName 是与当前始终“默认”检索的行关联的名称。
对象 databaseHelper 是 SQLiteOpenHelper 类的扩展。
readFromCursor 函数从光标中读取项目,并正常工作,问题是当cursor.moveToFirst() 返回 false 时它没有被调用。
public ConnectionInfo getConnectionByName(String connectionName) {
ConnectionInfo info = null;
SQLiteDatabase db = databaseHelper.getWritableDatabase();
Cursor cursor = db.rawQuery(STMT_SELECT_BY_NAME , new String[]{connectionName});
if (cursor != null) {
if (cursor.moveToFirst()) {
info = readFromCursor(cursor);
}
cursor.close();
}
DBRefcounter.closeDB(db);
return info;
}
调用自:
public ConnectionInfo createConnectionInfo(String connectionName, String siteURL, String subsite, String username, String password){
ConnectionInfo info = getConnectionByName(connectionName);
if(info == null){
SQLiteDatabase db = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_CONNECTION_NAME, connectionName);
values.put(COLUMN_SERVER_URL, siteURL);
values.put(COLUMN_SUBSITE, subsite);
values.put(COLUMN_USERNAME, username);
values.put(COLUMN_PASSWORD, password);
values.put(COLUMN_LAST_ACCESS_TIME, System.currentTimeMillis());
long id = db.insert(TABLE_CONNECTION, null, values);
DBRefcounter.closeDB(db);//clalls db.close and lowers counter
if(id >= 0){
//Build object to return
}
}
else{
//update the existing object
}
return info;
}
更新:
谁能告诉我 .close() 和 releaseReference 方法之间的区别?根据 api,它们应该是相同的,但它们表现出不同的行为。
【问题讨论】:
-
这样检查:
if(cursor != null && cursor.moveToFirst()){} -
确实没有足够的信息来回答。可能是数据更改或查询更改(例如
connectionName)参数。 -
游标对象永远不会为空,永远不会抛出异常,这是最困扰我的。在当前测试用例中,connectionName 参数始终为“默认”。如果您缺少任何信息,请告诉我们,以便我们尝试提供。
-
这个问题解决了吗?