Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SQLite:尝试重新打开已关闭的对象_Android_Android Sqlite_Android Cursor - Fatal编程技术网

Android SQLite:尝试重新打开已关闭的对象

Android SQLite:尝试重新打开已关闭的对象,android,android-sqlite,android-cursor,Android,Android Sqlite,Android Cursor,我试图从基于ISBN的库存表中获取某些图书数据。 但是,我得到一个错误:“尝试重新打开一个已经关闭的对象”。只有当我单击一个listView对象,转到另一个屏幕,通过“finish()”返回到此页面,然后尝试单击另一个listView对象时,才会发生此错误。我移动了字符串searchEntries[]=InventoryAdapter.getInventoryEntriesByISBN(searchQuery,isbn[position])从onClickListener到onClickList

我试图从基于ISBN的库存表中获取某些图书数据。 但是,我得到一个错误:“尝试重新打开一个已经关闭的对象”。只有当我单击一个listView对象,转到另一个屏幕,通过“finish()”返回到此页面,然后尝试单击另一个listView对象时,才会发生此错误。我移动了
字符串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];
Add
SQLiteDatabase 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文档,声明“创建和/或打开数据库”非常感谢您的时间!!