我在参加此活动后开始一个新的错误,然后回来。当我第一次加载活动时,它不会发生。功能上一切正常......但我仍然得到这个错误。
错误/光标(1059):完成a 尚未停用的游标 或关闭。 database = /data/data/com.roger.testapp/databases/data, table = null,query = SELECT MAX(_id) 从记录
03-02 16:47:21.835: ERROR /光标(1059): android.database.sqlite.DatabaseObjectNotClosedException: 应用程序没有关闭光标 或已打开的数据库对象 这里
on onCreate:
mDbHelper = new CommonDbAdapter(this);
mDbHelper.open();
fillData();
fillData()在我的dbhelper中调用fetchNote,游标用于一些事情,如果rowId == 0,这意味着我没有选择一个项目来进入这个活动,我想得到最后一行那张桌子。如果rowId =其他东西,那么我抓住那一行。我认为这个问题出现在这里,我只是不确定。
public Cursor fetchNote(long rowId, String table, String columns) throws SQLException {
if (rowId == 0) {
String query = "SELECT MAX(_id) FROM record";
Cursor cursor = mDb.rawQuery(query, null);
rowId = 0;
if (cursor.moveToFirst())
{
rowId = cursor.getInt(0);
}
}
Cursor mCursor =
mDb.query(true, table, new String[] {KEY_ROWID,
columns}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
在onDestroy中:
super.onDestroy();
if (mDbHelper != null) {
mDbHelper.close();
}
另外,我是startManagingCursor
答案 0 :(得分:2)
我建议不要返回光标。这是一种稀缺资源。
在n层Java EE中,最佳做法是在创建它们的方法范围内关闭所有持久性资源(Connection,Statement和ResultSet)。将ResultSet映射到对象或集合中并关闭ResultSet。
我不知道Android上是否存在一些特殊内容会使此无效。
答案 1 :(得分:2)
请勿在{{1}}中关闭您的数据库。在您完成使用后立即关闭它(确保在关闭数据库之前关闭每个光标)。您可能无法在预期时调用onDestroy。
此外,在您完成使用后,请关闭onDestroy
对象。
编辑:
由于您的活动正在管理Cursor
,因此您可以考虑停止管理它并关闭Cursor
方法中的所有内容,然后在onPause
中再次打开所有内容并onResume
。如果您可以更改代码,以便不依赖于管理光标的活动,那么您就不需要保留打开的数据库对象并担心它们。
答案 2 :(得分:0)
看一下activity lifecycle - 您可以看到,当您离开活动(onPause
)时,如果其他活动需要内存,您的进程将被终止,但当您的用户返回活动,它会再次点击onCreate
。这次你打开一个新的CommonDbAdapter(但是你从未关闭过原始的) - 因此当你最终点击onDestroy
时,你只会关闭最新的mDbHelper。
正如其他人所说,最好的方法不是将光标从DBHelper传回,使用数据创建对象,关闭光标并将对象传回。一旦你使用了DBHelper,你也可以关闭它,如果你需要再次使用它,你总是可以创建另一个。