我有使用sqlite的这个数据库,我有关闭光标的问题,它说Application did not close the cursor or database object that was opened here
这里是logcat
10-18 08:40:56.354: E/Cursor(331): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210)
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
10-18 08:40:56.354: E/Cursor(331): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
10-18 08:40:56.354: E/Cursor(331): at standard.internet.marketing.mymovingfriend.SQLHandler.checkMove(SQLHandler.java:1094)
10-18 08:40:56.354: E/Cursor(331): at standard.internet.marketing.mymovingfriend.ListMovingNames$3.onKey(ListMovingNames.java:98)
10-18 08:40:56.354: E/Cursor(331): at android.view.View.dispatchKeyEvent(View.java:3735)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1667)
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1102)
10-18 08:40:56.354: E/Cursor(331): at android.app.Activity.dispatchKeyEvent(Activity.java:2063)
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
10-18 08:40:56.354: E/Cursor(331): at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
10-18 08:40:56.354: E/Cursor(331): at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 08:40:56.354: E/Cursor(331): at android.os.Looper.loop(Looper.java:123)
10-18 08:40:56.354: E/Cursor(331): at android.app.ActivityThread.main(ActivityThread.java:4627)
10-18 08:40:56.354: E/Cursor(331): at java.lang.reflect.Method.invokeNative(Native Method)
10-18 08:40:56.354: E/Cursor(331): at java.lang.reflect.Method.invoke(Method.java:521)
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-18 08:40:56.354: E/Cursor(331): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-18 08:40:56.354: E/Cursor(331): at dalvik.system.NativeStart.main(Native Method)
这个问题一直困扰着我3天。
这里有一些相关的代码:
public class SQLHandler {
public static final String KEY_MOVENAME = "movename";
public static final String KEY_ID1 = "_id";
public static final String KEY_ID5 = "_id";
public static final String KEY_MOVEDATE = "movedate";
public static final String KEY_TOTALMOVEWEIGHT = "totalmoveweight";
public static final String KEY_TOTALITEM = "totalitem";
private static final String DATABASE_NAME = "mymovingfriend";
private static final int DATABASE_VERSION = 1;
public static final String KEY_LISTITEMNAME = "listitemname";
public static final String KEY_LISTITEMWEIGHT = "listitemweight";
public static final String KEY_LISTITEMROOM = "listitemroom";
private static final String DATABASE_TABLE1 = "movingname";
private static final String DATABASE_TABLE5 = "listitem";
public static final String CREATE_TABLE_1 = "CREATE TABLE " + DATABASE_TABLE1 + " (" +
KEY_ID1 + " INTEGER PRIMARY KEY AUTOINCREMENT," +
KEY_MOVEDATE + " TEXT NOT NULL, " +
KEY_TOTALMOVEWEIGHT + " TEXT NOT NULL, " +
KEY_TOTALITEM + " INTEGER NOT NULL, " +
KEY_MOVENAME + " TEXT NOT NULL);";
public static final String CREATE_TABLE_2 = "CREATE TABLE " + DATABASE_TABLE2 + " (" +
KEY_ID2 + " INTEGER PRIMARY KEY AUTOINCREMENT," +
KEY_ROOMMOVEHOLDER + " TEXT NOT NULL, " +
KEY_ROOMWEIGHT + " TEXT NOT NULL, " +
KEY_ROOM + " TEXT NOT NULL);";
public static final String CREATE_TABLE_5 = "CREATE TABLE " + DATABASE_TABLE5 + " (" +
KEY_ID5 + " INTEGER PRIMARY KEY AUTOINCREMENT," +
KEY_LISTITEMNAME + " TEXT NOT NULL, " +
KEY_LISTITEMWEIGHT + " TEXT NOT NULL, " +
KEY_LISTITEMROOM + " TEXT NOT NULL);";
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class DbHelper extends SQLiteOpenHelper{
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_TABLE_1);
db.execSQL(CREATE_TABLE_2);
db.execSQL(CREATE_TABLE_3);
db.execSQL(CREATE_TABLE_4);
db.execSQL(CREATE_TABLE_5);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE1);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE2);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE3);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE4);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE5);
onCreate(db);
}
}
public SQLHandler(Context c){
ourContext = c;
}
public SQLHandler open() throws SQLException{
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close(){
ourDatabase.close();
ourHelper.close();
}
public long createMove(String smovename){
ContentValues cv = new ContentValues();
cv.put(KEY_MOVENAME, smovename);
cv.put(KEY_MOVEDATE, "Not yet set");
cv.put(KEY_TOTALMOVEWEIGHT, "0");
cv.put(KEY_TOTALITEM, 0);
return ourDatabase.insert(DATABASE_TABLE1, null, cv);
}
public void createList(){
String[] sroom = new String[]{"Kitchen", "Bedroom", "Dinning Room"};
String[] sitem = new String[]{"Dishwasher", "Bed", "Table"};
String[] sweight = new String[]{"40", "25", "15"};
for (int i = 0; i < sroom.length; i++) {
cv.put(KEY_LISTITEMROOM, sroom[i]);
cv.put(KEY_LISTITEMNAME, sitem[i]);
cv.put(KEY_LISTITEMWEIGHT, sweight[i]);
ourDatabase.insert(DATABASE_TABLE5, null, cv);
}
}
public void setMoveDate(String smovedate, String smovename){
ContentValues cv = new ContentValues();
cv.put(KEY_MOVEDATE, smovedate);
ourDatabase.update(DATABASE_TABLE1, cv, KEY_MOVENAME + "='" + smovename + "'", null);
}
public void setMoveWeight(String smoveweight, String smovename){
ContentValues cv = new ContentValues();
cv.put(KEY_TOTALMOVEWEIGHT, smoveweight);
ourDatabase.update(DATABASE_TABLE1, cv, KEY_MOVENAME + "='" + smovename + "'", null);
}
public void setTotalItem(String smovename, int imoveitem){
ContentValues cv = new ContentValues();
cv.put(KEY_TOTALITEM, imoveitem);
ourDatabase.update(DATABASE_TABLE1, cv, KEY_MOVENAME + "='" + smovename + "'", null);
}
public void renameRoom(String movename, String roomname, String currentroom){
ContentValues cv = new ContentValues();
cv.put(KEY_ROOM, roomname);
ourDatabase.update(DATABASE_TABLE2, cv, KEY_ROOMMOVEHOLDER + "='" + movename + "'" + " AND " + KEY_ROOM + "='" + currentroom + "'", null);
}
public void setRoomWeight(String sroomweight, String smovename, String sroomname){
ContentValues cv = new ContentValues();
cv.put(KEY_ROOMWEIGHT, sroomweight);
ourDatabase.update(DATABASE_TABLE2, cv, KEY_ROOMMOVEHOLDER + "='" + smovename + "'" + " AND " + KEY_ROOM + "='" + sroomname + "'", null);
}
public long addRooms(String sroommoveholder, String sroom){
ContentValues cv = new ContentValues();
cv.put(KEY_ROOMMOVEHOLDER, sroommoveholder);
cv.put(KEY_ROOM, sroom);
cv.put(KEY_ROOMWEIGHT, "0");
return ourDatabase.insert(DATABASE_TABLE2, null, cv);
}
public long addNewItems(String sitemmoveholder, String sroomholder, String sitemname, String sitemvalue, String sitemweight){
ContentValues cv = new ContentValues();
cv.put(KEY_ITEMMOVEHOLDER, sitemmoveholder);
cv.put(KEY_ROOMHOLDER, sroomholder);
cv.put(KEY_ITEMNAME, sitemname);
cv.put(KEY_ITEMVALUE, sitemvalue);
cv.put(KEY_ITEMWEIGHT, sitemweight);
return ourDatabase.insert(DATABASE_TABLE3, null, cv);
}
public void updateItems(String sitemmoveholder, String sroomholder, String sitemname, String sitemvalue, String sitemweight){
ContentValues cv = new ContentValues();
cv.put(KEY_ITEMVALUE, sitemvalue);
cv.put(KEY_ITEMWEIGHT, sitemweight);
ourDatabase.update(DATABASE_TABLE3, cv, KEY_ITEMMOVEHOLDER + "='" + sitemmoveholder + "'" + " AND " +
KEY_ROOMHOLDER + "='" + sroomholder + "'" + " AND " + KEY_ITEMNAME + "='" + sitemname + "'", null);
}
public Cursor getMove(){
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME};
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE1, columns, null, null, null, null, null);
} catch (Exception e) {
c.close();
}
return c;
}
public String getTotalWeight(String m) throws SQLException{
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME, KEY_MOVEDATE, KEY_TOTALMOVEWEIGHT};
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE1, columns, KEY_MOVENAME + "= '" + m + "'", null, null, null, null);
if (c != null) {
c.moveToFirst();
String totalWeight = c.getString(3);
return totalWeight;
}
} catch (Exception e) {
c.close();
}
return null;
}
public String getTotalWeightLBS(String m) throws SQLException{
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME, KEY_MOVEDATE, KEY_TOTALMOVEWEIGHT};
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE1, columns, KEY_MOVENAME + "= '" + m + "'", null, null, null, null);
if (c != null) {
c.moveToFirst();
int x = Integer.parseInt(c.getString(3)) * 7;
String totalWeight = "" + x + " lbs";
return totalWeight;
}
} catch (Exception e) {
c.close();
}
return null;
}
public String getDateMove(String md){
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME, KEY_MOVEDATE};
Cursor c = null;try {
c = ourDatabase.query(DATABASE_TABLE1, columns, KEY_MOVENAME + "= '" + md + "'", null, null, null, null);
if (c != null) {
c.moveToFirst();
String moveDate = c.getString(2);
return moveDate;
}
} catch (Exception e) {
c.close();
}
return null;
}
public ArrayList<String> loadRooms(String mn) throws SQLException{
String[] columns = new String[]{KEY_ID2, KEY_ROOMMOVEHOLDER, KEY_ROOM};
ArrayList<String> array = new ArrayList<String>();
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE2, columns,KEY_ROOMMOVEHOLDER + "='" + mn + "'",
null, null, null, null);
int iroom = c.getColumnIndex(KEY_ROOM);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
array.add(c.getString(iroom));
}
} catch (Exception e) {
c.close();
}
return array;
}
public void deleteMove(String m) throws SQLException{
ourDatabase.delete(DATABASE_TABLE1, KEY_MOVENAME + "='" + m + "'", null);
ourDatabase.delete(DATABASE_TABLE2, KEY_ROOMMOVEHOLDER + "='" + m + "'", null);
ourDatabase.delete(DATABASE_TABLE3, KEY_ITEMMOVEHOLDER + "='" + m + "'", null);
ourDatabase.delete(DATABASE_TABLE4, KEY_TODOMOVE + "='" + m + "'", null);
}
public ArrayList<String> getitems(){
String[] columns = new String[]{KEY_ID5, KEY_ITEMNAME};
ArrayList<String> items;
items = new ArrayList<String>();
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE5, columns, null, null, null, null, null);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
items.add(c.getString(1));
}
} catch (Exception e) {
c.close();
}
return items;
}
public ArrayList<String> getitemweight(){
String[] columns = new String[]{KEY_ID5, KEY_ITEMWEIGHT};
ArrayList<String> items = new ArrayList<String>();
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE5, columns, null, null, null, null, null);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
items.add(c.getString(1));
}
} catch (Exception e) {
c.close();
}
return items;
}
public ArrayList<String> getitemclass(){
String[] columns = new String[]{KEY_ID5, KEY_LISTITEMROOM};
ArrayList<String> items = new ArrayList<String>();
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE5, columns, null, null, null, null, null);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
items.add(c.getString(1));
}
} catch (Exception e) {
c.close();
}
return items;
}
}
答案 0 :(得分:21)
您未关注getDateMove
,getTotalWeightLBS
,loadRooms
,...
不再需要光标的地方。在那些方法中使用try-finally,它将保证即使在抛出异常发生时也在finally块中执行代码。
更改方法中的代码:
try{
// get data from cursor
} catch (Exception e) {
c.close();
}
到此:
try {
// get data from cursor
} catch (Exception e) {
// exception handling
} finally {
if(c != null){
c.close();
}
}
答案 1 :(得分:9)
关闭finally
中的光标将保证它将被关闭;
public void myfunc() {
Cursor c = null;
try {
c = ... // Open cursor here
return .... // maybe return something
} finally {
if(c != null) { c.close(); }
}
}
答案 2 :(得分:6)
如果一个元素正在实现AutoCloseable(就像Cursor.class
那样),我建议你做一个try-with-resources
,就像描述here一样。
如果您使用Retrolambda,则try-with-resources
向后移植。
所以你的代码:
Cursor cursor = db.query("tableName", columns, null, null, null, null, null);
try {
if (cursor.moveToFirst()) return cursor.getString(3);
else return null;
} finally {
cursor.close();
}
只会变成:
try (Cursor cursor = db.query("tableName", columns, null, null, null, null, null)) {
if (cursor.moveToFirst()) return cursor.getString(3);
else return null;
}
答案 3 :(得分:0)
使用活动的onStop()
或onDestroy()
方法关闭数据库!
答案 4 :(得分:0)
您正尝试使用
关闭catch块中的光标catch (Exception e) {
c.close();
}
但如果你没有得到任何例外,那么它将如何关闭
所以把它放在finally块
中finally {
c.close();
}
答案 5 :(得分:0)
试试这个,
在onStop()
或onDestroy()
检查光标是否为空
@Override
public void onStop(){
Cursor cursor;
if(cursor!=null){
cursor.close();}
}
如果没有,则关闭光标。
修改强>
关闭数据库对象
DatabaseObject db;
if(db!=null)
{ db.close();}
希望它有所帮助。
答案 6 :(得分:0)
如果您使用Kotlin(也可以通过Java以某种不同的方式使用Java)以及Android 4.1及更高版本,则可以使用以下方法:
cursor?.use {
//..do stuff
}
例如,您可以选中here。
如果要使用Java,请执行以下操作:
try (Cursor cursor = ...) {
// do something
}