我有一个问题,我的数据库句柄在我的测试期间被关闭,我不知道为什么。
@Before
方法正确运行,但@Test
方法抛出异常:尝试重新打开已关闭的对象。我没有在我的代码中的任何地方关闭它,所以我不确定它是如何关闭的。
标记为@Test
的方法是目前测试中唯一的方法,因此之前没有其他测试正在运行。
有谁能帮我理解这里发生的事情?
测试
@RunWith(AndroidJUnit4.class)
public class DatabaseTest {
private Database subject;
private SQLiteDatabase wDB;
public DatabaseTest(){
DbHelper helper = new DbHelper(InstrumentationRegistry.getTargetContext());
subject = new Database(helper);
wDB = helper.getWritableDatabase();
}
// remove any preexisting records from the database
@Before
public void cleanSlate(){
wDB.delete(Database.ITEMS_TABLE, null, null);
}
@Test
public void testInsert(){
Cursor c;
Item i = getMockItem();
subject.update(i);
// (per below) DatabaseTest.java:46:
c = wDB.query(Database.ITEM_TABLE,Database.ALL_COLUMNS,null,null,null,null,null);
//...
错误
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.example.app.debug/databases/storage.db
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1257)
at com.example.app.data.local.DatabaseTest.testInsert(DatabaseTest.java:46)
更新方法
public void update(Item item){
SQLiteDatabase wDB = helper.getWritableDatabase();
ContentValues cv = entryToContentValues(item);
wDB.insertWithOnConflict(ITEM_TABLE, null, cv, SQLiteDatabase.CONFLICT_REPLACE );
wDB.close();
}
答案 0 :(得分:0)
问题是您正在使用update
方法关闭数据库,因此尝试在第46行运行查询时数据库已关闭。
一种解决方案是不在update方法中关闭数据库。但是,您应该在完成数据库后关闭它。
另一种解决方案可能是在查询之前但在getWriteableDatabase();
之后调用update
。
其他解决方案可能只有一个单例,从而确保您只有一个实例/连接,然后只有在应用程序被销毁时才关闭数据库(我在我正在使用的应用程序中使用此方法)
P.S。您还应关闭游标,然后完成它们,因为它们可能导致太多打开错误/问题。我个人倾向于将光标关闭到活动onDestroy
方法中。