ISBNに基づいて在庫テーブルから特定の書籍データを取得しようとしています。ただし、「すでに閉じているオブジェクトを再度開こうとしています」というエラーが発生します。このエラーは、listViewオブジェクトをクリックして別の画面に移動し、「finish()」を使用してこのページに戻ってから、別のlistViewオブジェクトをクリックしようとした場合にのみ発生します。 String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]);
をonClickListener
からonClickListener
の前の前のforループに移動しました。今では動作します。
「finish()」を介して別のアクティビティからこのアクティビティに戻った後、getInventoryEntriesByISBNを取得しようとすると、なぜ機能しないのですか?
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]);
InventoryAdapter.Java(最も関連する部分)
public String[] getInventoryEntriesByISBN(String search, String ISBN)
{
String[] searchEntry = new String [9];
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
for(int i = 0; i < 9; i++)
searchEntry[i] = "Not Found";
return searchEntry;
}
cursor.moveToFirst();
//put data into respective variable
int publish = cursor.getInt(cursor.getColumnIndex("PUBLISH_DATE"));
String publishdate = ((Integer)publish).toString();
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
String callNumber = cursor.getString(cursor.getColumnIndex("CALL_NUMBER"));
int available = cursor.getInt(cursor.getColumnIndex("AVAILABLE_COUNT"));
String availablecount = ((Integer)available).toString();
int inventory = cursor.getInt(cursor.getColumnIndex("INVENTORY_COUNT"));
String inventorycount = ((Integer)inventory).toString();
int due = cursor.getInt(cursor.getColumnIndex("DUE_PERIOD"));
String dueperiod = ((Integer)due).toString();
int checkoutcount = cursor.getInt(cursor.getColumnIndex("COUNT"));
String count = ((Integer)checkoutcount).toString();
//combine variables into one array
searchEntry[0] = ISBN;
searchEntry[1] = title;
searchEntry[2] = author;
searchEntry[3] = publishdate;
searchEntry[4] = callNumber;
searchEntry[5] = availablecount;
searchEntry[6] = inventorycount;
searchEntry[7] = dueperiod;
searchEntry[8] = count;
cursor.close();
return searchEntry;
}
public String getTitleAndAuthorByISBN(String ISBN)
{
int entriesFound = getNumSearchEntries(ISBN);
if(entriesFound==0)
entriesFound = 1;
String searchEntry;
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
searchEntry = "Not Found";
return searchEntry;
}
cursor.moveToFirst();
//put data into respective variable
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
//combine variables into one String
searchEntry = title + " / " + author;
//close cursor and return
cursor.close();
return searchEntry;
}
DataBaseHelper.Java
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);
}
}
このエラーは、アイテムをクリックして別の画面に移動し、「finish()」を使用してこのページに戻ってから、別のlistViewオブジェクトをクリックしようとした場合にのみ発生します。
文字列searchEntries [] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery、isbn [position]);を移動しました。 onClickListenerからonClickListenerの前の前のforループに移動し、動作するようになりました。
正しいSearchResultsScreenは次のとおりです。
SearchResultsScreen.Java
// 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];
クエリを実行する前にデータベース接続を確認してください。
if (!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();
}
それでも疑問がある場合は、遠慮なく私にpingしてください。ありがとうございました。
これはあなたの問題です
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();
への変更
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
{
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
//combine variables into one String
searchEntry = title + " / " + author;
}
_public String[] getInventoryEntriesByISBN(String search, String ISBN)
{
String[] searchEntry = new String [9];
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
_
生のクエリを実行する前に、このコードにSQLiteDatabase db = this.getWritableDatabase();
を追加します