我们一直在设置一个 Android 应用程序,但在使用 SQLite 时遇到了一个奇怪的错误,即相同的查询有时会提供结果,有时则不会。
运行以下代码时,它可能会返回请求的行,或者cursor.moveToFirst 可能会返回 false。导致返回 null。
我一直无法弄清楚为什么 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,它们应该是相同的,但它们显示不同的行为。
最佳答案
这可能是解释:
连续调用失败,因为您没有适本地终止第一个调用:
- 在返回之前,需要调用db.close和cusrsor.close()。 db.close 更为重要。
- 不这样做会导致第二次调用时出错,从而导致游标为空。此异常本质上关闭了数据库。因此第三次调用会成功。
关于java - 有时 SQLite 查询 android 上的光标为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24181972/