我在SQLite类中关闭Cursor有问题。当我关闭光标并在最后一个块(SQLiteDatabase
)中DBHelper
时,我无法读取其他类中的数据(无法重新打开关闭的光标错误)但是当我没有关闭Cursor和SQLiteDatabase
时,我就会出现内存泄漏错误。
DHHelper.java:
//...
public Cursor selectData(String selectVal, String tabName){
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = null;
try {
String areaTyp = "SELECT " + selectVal + " FROM " + tabName;
c = db.rawQuery(areaTyp, null);
return c;
} finally {
c.close();
db.close();
}
}
//...
UserMenager.java
public List<UserModel> getUsersList(){
List<UserModel> allUsers = new ArrayList<UserModel>();
final DBHelper db = new DBHelper(appStatic.CONTEX);
Cursor c = db.selectData("*","User");
if (c.moveToFirst()) {
while (!c.isAfterLast()) {
allUsers.add(new UserModel(c.getString(c.getColumnIndex("cms_id")),
c.getString(c.getColumnIndex("login")),
c.getString(c.getColumnIndex("name")),
c.getString(c.getColumnIndex("active")),
c.getString(c.getColumnIndex("avatar")),
c.getString(c.getColumnIndex("gtoken"))));
c.moveToNext();
}
}
c.close();
db.close();
return allUsers;
}
也许我应该以其他方式执行此操作并且返回Cursor的函数是个坏主意?
修改 当我运行应用程序时,我有错误:
java.lang.IllegalStateException:尝试重新打开已经关闭的 object:SQLiteQuery:SELECT * FROM User
在UserMenager.java中,行
if (c.moveToFirst()) {
答案 0 :(得分:0)
return
无法访问后的代码 - 将永远不会被执行。
答案 1 :(得分:0)
我建议从selectData
类返回你想要的最终结果,即ArrayList。然后,您可以在selectData
方法完成后立即关闭光标和数据库。
e.g。 : -
public ArrayList<UserModel> selectData(String selectVal, String tabName){
SQLiteDatabase db = this.getWritableDatabase(); //<<<< getReadable will most likely return a writeable database anyway
ArrayList<UserModel> rv = new ArrayList<>();
Cursor c = db.query(
tabName,
new String[]{selectVal},
null,
null,
null,
null,
null
);
while (c.moveToNext()) {
rv.add(new UserModel(
c.getString(c.getColumnIndex("cms_id")),
c.getString(c.getColumnIndex("login")),
c.getString(c.getColumnIndex("name")),
c.getString(c.getColumnIndex("active")),
c.getString(c.getColumnIndex("avatar")),
c.getString(c.getColumnIndex("gtoken"))
));
}
c.close();
db.close();
return rv;
}
同时: -
public List<UserModel> getUsersList(){
List<UserModel> allUsers = new ArrayList<UserModel>();
final DBHelper db = new DBHelper(appStatic.CONTEX);
return selectData("*","Users");
}
try
/ catch
往往会造成比原本造成的更多挫折和困惑。rawQuery
和execSQL
方法(在这种情况下,query
是方便的方法)。query
便捷方法的字符串。getReadableDatabase
很少按照
- 创建和/或打开数据库。这将是getWritableDatabase()返回的相同对象,除非出现一些问题,例如完整磁盘, 要求数据库以只读方式打开。在那种情况下,a 将返回只读数据库对象。如果问题得到解决,a 将来调用getWritableDatabase()可能会成功,在这种情况下 将关闭只读数据库对象和读/写对象 将来会被退回。 SQLiteDatabase getReadableDatabase