Android SQLite:尝试重新打开已关闭的对象
我试图从基于ISBN的库存表中获取某些图书数据。 但是,我得到一个错误:“尝试重新打开一个已经关闭的对象”。只有当我单击一个listView对象,转到另一个屏幕,通过“finish()”返回到此页面,然后尝试单击另一个listView对象时,才会发生此错误。我移动了Android SQLite:尝试重新打开已关闭的对象,android,android-sqlite,android-cursor,Android,Android Sqlite,Android Cursor,我试图从基于ISBN的库存表中获取某些图书数据。 但是,我得到一个错误:“尝试重新打开一个已经关闭的对象”。只有当我单击一个listView对象,转到另一个屏幕,通过“finish()”返回到此页面,然后尝试单击另一个listView对象时,才会发生此错误。我移动了字符串searchEntries[]=InventoryAdapter.getInventoryEntriesByISBN(searchQuery,isbn[position])从onClickListener到onClickList
字符串searchEntries[]=InventoryAdapter.getInventoryEntriesByISBN(searchQuery,isbn[position])
从onClickListener
到onClickListener
之前的前一个for循环,现在它可以工作了
如果我通过“finish()”从另一个活动返回此活动后,尝试通过ISBN获取InventoryEntries,为什么不起作用
该错误出现在SearchResultsScreen:
String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]);
扩展而言,发生在InventoryAdapter:
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
SearchResultsScreen.java
// Set up search array
for(int i = 0; i < isbn.length; i++)
{
searchArray.add(new InventoryItem(isbn[i], InventoryAdapter.getTitleAndAuthorByISBN(isbn[i])));
}
Toast.makeText(getApplicationContext(), "searchArray.size()="+searchArray.size(), Toast.LENGTH_LONG).show();
// add data in custom adapter
adapter = new CustomAdapter(this, R.layout.list, searchArray);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
// On Click ========================================================
dataList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]);
public class DataBaseHelper extends SQLiteOpenHelper
{
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "database.db";
// ============================ End Variables ===========================
public DataBaseHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
public DataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Called when no database exists in disk and the helper class needs
// to create a new one.
@Override
public void onCreate(SQLiteDatabase _db)
{
_db.execSQL(LoginDataBaseAdapter.USER_TABLE_CREATE);
_db.execSQL(CheckOutDataBaseAdapter.CHECKOUT_TABLE_CREATE);
_db.execSQL(InventoryAdapter.INVENTORY_TABLE_CREATE);
_db.execSQL(StatisticsAdapter.STATISTICS_TABLE_CREATE);
}
// Called when there is a database version mismatch meaning that the version
// of the database on disk needs to be upgraded to the current version.
@Override
public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion)
{
// Log the version upgrade.
Log.w("TaskDBAdapter", "Upgrading from version " +_oldVersion + " to " +_newVersion + ", which will destroy all old data");
// Upgrade the existing database to conform to the new version. Multiple
// previous versions can be handled by comparing _oldVersion and _newVersion
// values.
// on upgrade drop older tables
_db.execSQL("DROP TABLE IF EXISTS " + LoginDataBaseAdapter.USER_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + CheckOutDataBaseAdapter.CHECKOUT_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + InventoryAdapter.INVENTORY_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + StatisticsAdapter.STATISTICS_TABLE_CREATE);
// Create a new one.
onCreate(_db);
}
}
// Set up search array
final String Entries[][] = new String[isbn.length][9];
for(int i = 0; i < isbn.length; i++)
{
searchArray.add(new InventoryItem(isbn[i], InventoryAdapter.getTitleAndAuthorByISBN(isbn[i])));
Entries[i] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[i]);
}
Toast.makeText(getApplicationContext(), "searchArray.size()="+searchArray.size(), Toast.LENGTH_LONG).show();
// add data in custom adapter
adapter = new CustomAdapter(this, R.layout.list, searchArray);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
// On Click ========================================================
dataList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String searchEntries[] = Entries[position];
AddSQLiteDatabase db=this.getWritableDatabase()在执行原始查询之前,此代码中的代码>这是您的问题
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
for(int i = 0; i < 9; i++)
searchEntry[i] = "Not Found";
return searchEntry;
}
cursor.moveToFirst();
cursor.close();
只有当我单击某个项目,转到其他屏幕,通过“finish()”返回此页面,然后尝试单击另一个listView对象时,才会发生此错误
我移动了字符串searchEntries[]=InventoryAdapter.getInventoryEntriesByISBN(searchQuery,isbn[position]);从onClickListener到onClickListener之前的前一个for循环,现在它可以工作了
下面是正确的SearchResults屏幕:
SearchResultsScreen.java
// Set up search array
for(int i = 0; i < isbn.length; i++)
{
searchArray.add(new InventoryItem(isbn[i], InventoryAdapter.getTitleAndAuthorByISBN(isbn[i])));
}
Toast.makeText(getApplicationContext(), "searchArray.size()="+searchArray.size(), Toast.LENGTH_LONG).show();
// add data in custom adapter
adapter = new CustomAdapter(this, R.layout.list, searchArray);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
// On Click ========================================================
dataList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]);
public class DataBaseHelper extends SQLiteOpenHelper
{
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "database.db";
// ============================ End Variables ===========================
public DataBaseHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
public DataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Called when no database exists in disk and the helper class needs
// to create a new one.
@Override
public void onCreate(SQLiteDatabase _db)
{
_db.execSQL(LoginDataBaseAdapter.USER_TABLE_CREATE);
_db.execSQL(CheckOutDataBaseAdapter.CHECKOUT_TABLE_CREATE);
_db.execSQL(InventoryAdapter.INVENTORY_TABLE_CREATE);
_db.execSQL(StatisticsAdapter.STATISTICS_TABLE_CREATE);
}
// Called when there is a database version mismatch meaning that the version
// of the database on disk needs to be upgraded to the current version.
@Override
public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion)
{
// Log the version upgrade.
Log.w("TaskDBAdapter", "Upgrading from version " +_oldVersion + " to " +_newVersion + ", which will destroy all old data");
// Upgrade the existing database to conform to the new version. Multiple
// previous versions can be handled by comparing _oldVersion and _newVersion
// values.
// on upgrade drop older tables
_db.execSQL("DROP TABLE IF EXISTS " + LoginDataBaseAdapter.USER_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + CheckOutDataBaseAdapter.CHECKOUT_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + InventoryAdapter.INVENTORY_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + StatisticsAdapter.STATISTICS_TABLE_CREATE);
// Create a new one.
onCreate(_db);
}
}
// Set up search array
final String Entries[][] = new String[isbn.length][9];
for(int i = 0; i < isbn.length; i++)
{
searchArray.add(new InventoryItem(isbn[i], InventoryAdapter.getTitleAndAuthorByISBN(isbn[i])));
Entries[i] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[i]);
}
Toast.makeText(getApplicationContext(), "searchArray.size()="+searchArray.size(), Toast.LENGTH_LONG).show();
// add data in custom adapter
adapter = new CustomAdapter(this, R.layout.list, searchArray);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
// On Click ========================================================
dataList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String searchEntries[] = Entries[position];
//设置搜索数组
最终字符串条目[][]=新字符串[isbn.length][9];
for(int i=0;i 执行查询前检查数据库连接:
如果(!dbHelper.db.isOpen())
dbHelper.open();
您还可以再次使用cursor.requery();
进行相同的查询
最后,还必须关闭光标和数据库
cursor.close();
db.close();
编辑:
我已经创建了DBHelper
类,它扩展了SQLiteOpenHelper
,这个类是DatabaseHelper
类的内部类,这个类有以下方法
/** For OPEN database **/
public synchronized DatabaseHelper open() throws SQLiteException {
dbHelper = new DBHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
/** For CLOSE database **/
public void close() {
dbHelper.close();
}
如果您仍有疑问,请随时与我联系。谢谢。显示您的数据库类我编辑了问题以包括数据库类。post适配器代码。错误很明显,您正在关闭光标并删除此onCreate(\u db)
能否显示InventoryAdapter.INVENTORY\u TABLE\u CREATE
?结果表明,只有当我单击一个项目,转到另一个屏幕,通过“finish()”返回此页面,然后尝试单击另一个listView对象时,才会出现错误。我移动了字符串searchEntries[]=InventoryAdapter.getInventoryEntriesByISBN(searchQuery,isbn[position]);
从onClickListener到onClickListener之前的前一个for循环,现在它工作了。这是为什么?我不能添加'this.getWritableDatabase()',因为'this'指的是InventoryAdapter,而我的数据库在DataBaseHelper中。我尝试了'DataBaseHelper.getWritableDatabase()'我得到一个错误:无法从类型对非静态方法getWritableDatabase()进行静态引用SQLiteOpenHelper@user3152800您的问题是关闭光标,然后执行操作。请检查我的姿势a上下文,然后使用。或者尝试使用getActivity().getWritableDatabase
事实上,我有一些与该代码非常相似的东西,但我没有发布,因为该部分工作正常。此外,我有意返回一个包含文本“Not Found”的数组。但是searchEntry
如果count为1,则返回not found它返回什么?我编辑了问题以显示原始代码的其余部分,这些代码只是从表中获取数据并将其存储在数组中。它对我来说很好。这不是一个解决方案,您需要同步!!!,或者您可以在将来得到相同的错误,而不是open()
方法,你的从何而来?我的open
和close
方法只是打开和关闭数据库。所以你可以直接用数据库实例写,很抱歉,但我还是不明白..我有3个实例MyDbHelper dbHelper=new MyDbHelper();SQLiteDatabase dbr=dbHelper.getReadableDatabase(),dbw=dbHelper.getWriteableDatabase();
它们都没有open()
方法,但每个都有close()
方法…很抱歉打扰您,但我是Android新手,遇到了这个问题…现在我解决了保持打开(而不是关闭)的问题try catch finally
的finally
块中的帮助器和光标,但我觉得这不是解决方案,因为SDK引发了异常DatabaseObjectNotClosedException
@CliffBurton我已经编辑了我的答案,请检查。现在我明白了!所以“打开数据库”这意味着只需声明一个新的SQLiteOpenHelper
并调用其中一个getWritable/ReadableDatabase()
方法……现在我已经阅读了关于这些方法的更好的Adroid文档,声明“创建和/或打开数据库”非常感谢您的时间!!