android – 错误无法执行此操作,因为连接池已关闭

前端之家收集整理的这篇文章主要介绍了android – 错误无法执行此操作,因为连接池已关闭前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用sqlite数据库,并使用Alex LockWood Correctly Managing Your SQLite Database的一些代码

它工作得很好,但有时我得到错误“java.lang.IllegalStateException:无法执行此操作,因为连接池已关闭.
这是完整的错误

  1. 02-20 16:37:21.385: W/dalvikvm(25730): threadid=13: thread exiting with uncaught exception (group=0x41c122a0)
  2. 02-20 16:37:21.390: E/AndroidRuntime(25730): FATAL EXCEPTION: Timer-0
  3. 02-20 16:37:21.390: E/AndroidRuntime(25730): java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
  4. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteConnectionPool.throwIfClosedLocked(sqliteConnectionPool.java:963)
  5. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteConnectionPool.waitForConnection(sqliteConnectionPool.java:678)
  6. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteConnectionPool.acquireConnection(sqliteConnectionPool.java:349)
  7. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteSession.acquireConnection(sqliteSession.java:894)
  8. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteSession.executeForCursorWindow(sqliteSession.java:834)
  9. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteQuery.fillWindow(sqliteQuery.java:62)
  10. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteCursor.fillWindow(sqliteCursor.java:143)
  11. 02-20 16:37:21.390: E/AndroidRuntime(25730): at android.database.sqlite.sqliteCursor.getCount(sqliteCursor.java:133)
  12. 02-20 16:37:21.390: E/AndroidRuntime(25730): at com.uit.pokemon.DatabaseHandler.getStadiumStatusById(DatabaseHandler.java:533)
  13. 02-20 16:37:21.390: E/AndroidRuntime(25730): at playground.RoomActivity.checkTable(RoomActivity.java:276)
  14. 02-20 16:37:21.390: E/AndroidRuntime(25730): at playground.RoomActivity$6.run(RoomActivity.java:321)
  15. 02-20 16:37:21.390: E/AndroidRuntime(25730): at java.util.Timer$TimerImpl.run(Timer.java:284)
  16. 02-20 16:37:21.460: I/timertask cancel(25730): canceled

这里是导致错误代码

  1. public int getStadiumStatusById(int dataStadiumId){
  2. sqliteDatabase db = this.getReadableDatabase();
  3. Cursor cur = db.rawQuery("SELECT " + keyStadiumId + " as _id,"
  4. + keyRoomName + "," + keyP1Name + "," + keyP1PokemonName
  5. + "," + keyP1PokemonLevel + "," + keyP1PokemonHp + ","
  6. + keyP2Name + "," + keyP2PokemonName + ","
  7. + keyP2PokemonLevel + "," + keyP2PokemonHp + ","
  8. + keyTimeCreate + "," + keyStadiumStatus + " from "
  9. + tbl_stadium + " WHERE " + keyStadiumId + " = " + "'"
  10. + dataStadiumId + "'",new String[] {});
  11.  
  12. int stadiumStatus = 0;
  13. if(cur.getCount()>0)
  14. {
  15. cur.moveToFirst();
  16. stadiumStatus = cur.getInt(11);
  17. }
  18. db.close();
  19. cur.close();
  20. return stadiumStatus;
  21. }

我尝试了几个小时的谷歌搜索,但没有结果.请帮我解决.任何帮助将不胜感激.谢谢!

解决方法

我也在处理这个问题.我有一个理由,并且很乐意听取专家的意见.我做了很多假设,并得出一些不支持证据的结论.
我认为这个例外是在“返回体育馆状态”行上抛出的.在上面的几行中,您将此变量分配给Cursor的成员.我相信你实际上分配名称stadiumStatus来指向只存在于游标中的int变量.另一个可能性(这里的巨大飞跃)是Cursor.getInt()返回的项目实际上是一个指向开放数据库中的一个项目(一个方法?)的指针(由于它是开放的,它驻留在内存中).无论哪种方式,当您关闭Cursor和/或数据库,然后尝试返回stadiumStatus时,int指向Cursor中的地址或由Cursor传递,尝试跟随它,并在封闭的Cursor或封闭数据库(一个这些是您正在绘制的“数据池”.)
如果我是对的,我认为最好的解决办法是替换:

“stadiumStatus = cur.getInt(11);”

有:

“stadiumStatus = new Integer(cur.getInt(11));”

从而在内存中创建一个新的Integer,这个vm可以简单地转换为int,并且只依赖于其传统的可访问性范围.
这个答案是否有意义?我确信提问者已经过了这个问题,但我很想说可以说我回答了一个关于Stack Overflow的问题(或被告知为什么我错了,并且更好地了解了Cursors和DB).
编辑:这些答案暗示我可能是对的:
Android error: Cannot perform this operation because the connection pool has been closed
Will cursor be still alive after database is closed?在第二个答案中,具有巨大声望的用户DeeV称之为游标“持久连接”,这意味着它不是DB中返回值的简单集合.

猜你在找的Android相关文章