我有一个应用程序,其中不断抛出此异常......
04-25 18:47:38.024: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.035: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44dd1e68 on null that has not been deactivated or closed
04-25 18:47:38.035: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.035: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.044: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.064: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e4c048 on null that has not been deactivated or closed
04-25 18:47:38.064: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.064: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.074: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.094: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e35310 on null that has not been deactivated or closed
04-25 18:47:38.094: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.094: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.104: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.104: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e7f738 on null that has not been deactivated or closed
04-25 18:47:38.104: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.104: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.114: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.136: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e04a90 on null that has not been deactivated or closed
04-25 18:47:38.136: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.136: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.155: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.155: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e944f0 on null that has not been deactivated or closed
04-25 18:47:38.155: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.155: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.164: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.184: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e90548 on null that has not been deactivated or closed
04-25 18:47:38.184: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.184: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.194: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.194: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e6b0c8 on null that has not been deactivated or closed
04-25 18:47:38.194: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.194: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.204: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.225: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e4af40 on null that has not been deactivated or closed
04-25 18:47:38.237: INFO/dalvikvm(10290): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.245: INFO/dalvikvm(10290): at dalvik.system.NativeStart.run(Native Method)
我不明白为什么会这样。我关闭了所有游标,并且我在数据库之前关闭了游标......
即c.close()
db.close()
可能是什么问题?
提前谢谢。
编辑: 我认为这个类导致了异常,因为它是唯一一个处理数据库的
package com.helios.NauticDates;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class HandleDatabase {
public void executeSql(String query) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(
"/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
null, SQLiteDatabase.OPEN_READWRITE);
db.execSQL(query);
db.close();
}
public boolean checkCategory(String name) {
// TODO Auto-generated method stub
SQLiteDatabase db = SQLiteDatabase.openDatabase(
"/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
null, SQLiteDatabase.OPEN_READWRITE);
String query = "select * from EventCategories where categoryname ='"
+ name + "'";
Cursor c = db.rawQuery(query, null);
if (c.getCount() == 0) {
c.close();
db.close();
return true;
} else {
c.close();
db.close();
return false;
}
}
public String[][] getData(String[] columnnames, String tablename) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(
"/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
null, SQLiteDatabase.OPEN_READWRITE);
String query = "select ";
for (int i = 0; i < columnnames.length; i++) {
if (i == columnnames.length - 1)
query += columnnames[i] + " ";
else
query += columnnames[i] + ",";
}
query += "from " + tablename + " where eventid=128";
Cursor c = db.rawQuery(query, null);
String[][] result = new String[c.getColumnCount()][c.getCount()];
for (int i = 0; i < c.getColumnCount(); i++) {
c.moveToFirst();
for (int j = 0; j < c.getCount(); j++) {
result[i][j] = c.getString(c.getColumnIndex(columnnames[i]));
Log.i("getdata", result[i][j]);
c.moveToNext();
}
}
c.close();
db.close();
return result;
}
public boolean checkIfThereIsEvent(String cdate, Date currentdate) {
Date enddate = (Date) currentdate.clone();
enddate.setHours(0);
enddate.setMinutes(0);
enddate.setSeconds(0);
String edate = (String) android.text.format.DateFormat.format(
"yyyy-MM-dd", enddate);
Log.i("handledatabase", cdate + "-" + edate);
SQLiteDatabase db = SQLiteDatabase.openDatabase(
"/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
null, SQLiteDatabase.OPEN_READWRITE);
String query = "SELECT datetime(startdat, 'unixepoch') AS std, datetime(enddat, 'unixepoch') AS end FROM EventDetails WHERE ((std <= '"
+ cdate
+ "' AND end >= '"
+ cdate
+ "' )||( date(enddat,'unixepoch') = '1970-01-01' AND date(startdat,'unixepoch') = '"
+ edate + "')) LIMIT 1";
Log.i("thequery", query);
Cursor c = db.rawQuery(query, null);
if (c.getCount() > 0) {
c.close();
db.close();
return true;
}
{
c.close();
db.close();
return false;
}
}
public boolean checkEventInDatabase(String dateofchange, String eventid) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(
"/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
null, SQLiteDatabase.OPEN_READWRITE);
String query = "select * from EventDetails where eventid='"+eventid+"' limit 1";
Cursor c = db.rawQuery(query, null);
if(c.getCount()==0){
c.close();
db.close();
return false;
}
else{
query = "select * from EventDetails where eventid='"+eventid+"'and changed='"+dateofchange+"' limit 1";
c= db.rawQuery(query, null);
if(c.getCount()>0){
c.close();
db.close();
return true;
}
else{
c.close();
db.close();
return true;
}
}
}
public boolean checkIfEventChanged(String dateofchange, String eventid) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(
"/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
null, SQLiteDatabase.OPEN_READWRITE);
String query = "select * from EventDetails where eventid='"+eventid+"'and changed='"+dateofchange+"' limit 1";
Cursor c= db.rawQuery(query, null);
if(c.getCount()>0){
c.close();
db.close();
return false;
}
else{
c.close();
db.close();
return true;
}
}
}
答案 0 :(得分:2)
else
结束时您遗漏了checkIfThereIsEvent()
。
如果没有清除它,只需通过调用Cursor
记录您自己打开的每个Log
,然后比较日志条目以确定哪个是Cursor
被泄露了。
此外:
/data/data/com.helios.NauticDates
。使用SQLiteOpenHelper
或使用getDatabasePath()
。SQLiteOpenHelper
,将这些方法放在该类上,并保持SQLiteOpenHelper
更长时间(例如,您的活动或服务的生命周期,或整个应用的单身人士)答案 1 :(得分:2)
CommonsWare的补充:
在checkEventInDatabase()
中重新分配c
变量,如果c.getCount()
不为0,那么您可以创建一个永不关闭的光标。
请注意:每当你在一个循环中呼叫getCount()
或getColumnCount()
时,上帝会杀死一只小猫! (见getData()
)