Java 无法返回游标对象-从未显式调用close()错误
嘿。我试图将游标对象返回到我的活动中,它将在SimpleCorsOrAdapter中使用,但我遇到了一个Java 无法返回游标对象-从未显式调用close()错误,java,android,sqlite,jdbc,cursor,Java,Android,Sqlite,Jdbc,Cursor,嘿。我试图将游标对象返回到我的活动中,它将在SimpleCorsOrAdapter中使用,但我遇到了一个close()从未被显式调用的错误。我找不到任何解决这个错误的方法,我想这是一个无法解决的错误,哈哈 跟我想想 错误显示: close()从未被显式调用 数据库 “/data/data/com.example.myapp/databases/myDB.db” 还有一个警告: 在终结器中释放语句。 请确保您明确地调用 在光标上关闭():从中选择* 按持续时间描述联系_数据顺序 android.d
close()从未被显式调用的错误。我找不到任何解决这个错误的方法,我想这是一个无法解决的错误,哈哈
跟我想想
错误显示:
close()从未被显式调用
数据库
“/data/data/com.example.myapp/databases/myDB.db”
还有一个警告:
在终结器中释放语句。
请确保您明确地调用
在光标上关闭():从中选择*
按持续时间描述联系_数据顺序
android.database.sqlite.DatabaseObjectNotClosedException:
应用程序未关闭在此打开的游标或数据库对象
错误在这个方法中,即DataHandlerDB(处理数据库)类中
此方法通过以下方法用于我的活动:
public void setBasicContent() {
listview = (ListView) findViewById(R.id.list_view);
Log.i(LOG_TAG, "listview " + listview);
Cursor c = DataHandlerDB.selectTopCalls(this); // here I use the method
startManagingCursor(c);
adapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] {
DataHandlerDB.CONTACT_NAME_COL,
DataHandlerDB.CONTACT_NUMBER_COL,
DataHandlerDB.CONTACT_DURATION_COL,
DataHandlerDB.CONTACT_DATE_COL }, new int[] {
R.id.contact_name, R.id.phone_number, R.id.duration, R.id.date });
Log.i(LOG_TAG, "before setAdapter");
Toast.makeText(this, "Before setAdapter", Toast.LENGTH_SHORT).show();
listview.setAdapter(adapter);
}
我试图在这个方法中关闭游标和数据库,但当我这样做时,错误并没有被修复,它也不会打印我的列表
我试图在selectValues()方法上关闭它,但当我这样做时,它说,试图重新打开已经关闭的游标(类似于这样)
我还试图在onDestroy()和onStop()中关闭光标和数据库,但没有成功
这就是为什么我认为没有解决办法。我该怎么办
类DataHandlerDB.java具有createDB()方法:
还有一个名为OpenHelper的内部类(扩展了SQLiteOpenHelper)
所以任何人都可以帮我解决这个问题??谢谢 不要在每个静态方法中创建新的OpenHelper,而是使用当前上下文实例化您的DataHandlerDB
,并让类保存一个由getWritableDatabase
填充的变量。您正在创建由不同的SQLiteOpenHelper
对象创建的多个游标对象,Android不喜欢这样做
有关其他信息,请查看此链接:
在我看来,这就是你在做的事情
public class DataHandlerDB{
public static SQLiteDatabase createDB(Context ctx) {
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
...
return db;
}
public static Cursor selectTopCalls(Context ctx) {
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase(); // error is here
...
return c;
}
}
这会导致多个并发的SQLiteOpenHelper
对象和多个SQLiteDatabase
对象以及当前的锁定情况
与其执行多个静态调用,不如创建一个使用一致上下文实例化的DataHandler类,然后进行常规调用(而不是静态调用):
创建此对象时,它将保持1OpenHelper
和1SQLiteDatabase
。这将缓解SQLite希望在访问数据库之前关闭数据库的问题
不要忘记在活动的onDestroy
方法中关闭数据库。当你说:用当前上下文实例化DataHandlerDB,让类包含一个由getWritableDatabase填充的变量时,我不明白。你能给我举个清楚的例子吗?谢谢我按你说的做了。但它一直显示相同的错误,但现在在DataHandlerDB构造函数的行中:_db=_helper.getWritableDatabase()@cyberrog你可能在某处仍然有一个开放的连接。您是否已关闭其他活动中以前的所有连接?如果您使用我概述的方法,那么请确保在使用完DB后也调用了handler.close()
。
public static SQLiteDatabase createDB(Context ctx) {
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
helper.onOpen(db);
db.close();
return db;
}
public static class OpenHelper extends SQLiteOpenHelper {
private final Context mContext;
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String[] sql = mContext.getString(
R.string.MyString_OnCreate).split("\n");
db.beginTransaction();
try {
execMultipleSQL(db, sql);
db.setTransactionSuccessful();
} catch (SQLException e) {
Log.e("Error creating tables and debug data", e.toString());
throw e;
} finally {
db.endTransaction();
}
}
private void execMultipleSQL(SQLiteDatabase db, String[] sql) {
for (String s : sql) {
if (s.trim().length() > 0) {
db.execSQL(s);
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/*
* Log.w("My Database",
* "Upgrading database, this will drop tables and recreate.");
* db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db);
*/
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
}
}
public class DataHandlerDB{
public static SQLiteDatabase createDB(Context ctx) {
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
...
return db;
}
public static Cursor selectTopCalls(Context ctx) {
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase(); // error is here
...
return c;
}
}
public class DataHandlerDB{
OpenHelper _helper;
SQLiteDatabse _db;
public DataHandlerDB( Context ctx ){
_helper = new OpenHelper(ctx);
_db = _helper.getWritableDatabase();
}
public SQLiteDatabase createDB() {
...
return db;
}
public Cursor selectTopCalls() {
...
return c;
}
}
public void setBasicContent() {
...
DataHandlerDB handler = new DataHandlerDB( this );
Cursor c = handler.selectValues(); //.selectTopCalls()?
...
}