现在的位置: 首页 > 综合 > 正文

close() was never explicitly called on database 和 database is locked 错误原因

2012年10月25日 ⁄ 综合 ⁄ 共 3819字 ⁄ 字号 评论关闭

1.cursor 使用完没有关闭。

2.数据库用完没有关闭。

3.数据库重复新建(new了多个对象)。

我的错误是new了多个对象。

LogCat 报错信息:

[java] view
plain
copy

  1. 02-13 11:58:13.759: ERROR/Database(432): close() was never explicitly called on database '/data/data/com.yyt.ui/databases/yyt.db'   
  2. 02-13 11:58:13.759: ERROR/Database(432): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here  
  3. 02-13 11:58:13.759: ERROR/Database(432): at android.database.sqlite.SQLiteDatabase.(SQLiteDatabase.java:1847)  
  4. 02-13 11:58:13.759: ERROR/Database(432): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)  
  5. 02-13 11:58:13.759: ERROR/Database(432): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854)  
  6. 02-13 11:58:13.759: ERROR/Database(432): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847)  
  7. 02-13 11:58:13.759: ERROR/Database(432): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:544)  
  8. 02-13 11:58:13.759: ERROR/Database(432): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)  
  9. 02-13 11:58:13.759: ERROR/Database(432): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)  
  10. 02-13 11:58:13.759: ERROR/Database(432): at com.taobao.htc.db.RecordDBHelper.query(RecordDBHelper.java:49)  
  11. 02-13 11:58:13.759: ERROR/Database(432): at com.taobao.htc.manage.RecordDBopt.get(RecordDBopt.java:78)  
  12. 02-13 11:58:13.759: ERROR/Database(432): at com.taobao.htc.manage.RecordMessage.sendMseeage(RecordMessage.java:111)  
  13. 02-13 11:58:13.759: ERROR/Database(432): at com.taobao.htc.manage.RecordMessage.sendMseeage(RecordMessage.java:87)  
  14. 02-13 11:58:13.759: ERROR/Database(432): at com.taobao.htc.Report.run(Report.java:49)  
  15. 02-13 11:58:13.759: ERROR/Database(432): at java.lang.Thread.run(Thread.java:1019)  
  16. 02-13 11:58:13.830: WARN/ActivityManager(62): Launch timeout has expired, giving up wake lock!  
  17. 02-13 11:58:14.381: DEBUG/dalvikvm(432): GC_CONCURRENT freed 771K, 57% free 2908K/6727K, external 2013K/2137K, paused 7ms+5ms  
  18. 02-13 11:58:14.630: DEBUG/dalvikvm(432): GC_FOR_MALLOC freed 867K, 58% free 2836K/6727K, external 2013K/2137K, paused 178ms  


发生错误原因分析:

主要错误:

[java] view
plain
copy

  1. 02-13 11:58:13.759: ERROR/Database(432): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here  


出错处代码

[java] view
plain
copy

  1. SQLiteDatabase db = getWritableDatabase();  

 

意思是指在此处打开数据库操作之前,应用程序没有关闭游标或数据库对象。

在应用中,对数据库操作完成后,应该对游标及数据库进行关闭操作

[html] view
plain
copy

  1. if (!cur.isClosed()) {  
  2.     cur.close();  
  3. }  
  4. db.close();  


解决办法:

检查操作数据库的相关源代码,增加关闭“cursor or database object”的代码 。

总结一下Activity.startManagingCursor方法:


c=cr.query(Uri.parse(Values.contentA + Values.contentB),
null, Values.table_02_name+"="+"\""+str+"\";",

                                null, null);
                startManagingCursor(c);
                c.moveToFirst();


如果操作cursor不是在Activity中,不能用startManagingCursor函数的 

 
1.这个方法使用的前提是:游标结果集里有很多的数据记录。
所以,在使用之前,先对Cursor是否为null进行判断,如果Cursor != null,再使用此方法
 
2.如果使用这个方法,最后也要用stopManagingCursor()来把它停止掉,以免出现错误。
 
3.使用这个方法的目的是把获取的Cursor对象交给Activity管理,这样Cursor的生命周期便能和Activity自动同步,
省去自己手动管理。

——————————————————————————————————我是分割线————————————————————————————————————

而当我们遇到Caused by: android.database.sqlite.SQLiteException: database is locked这个问题时,主要原因大部分都是多线程多数据库进行操作了。这个时候你需要在需要操作数据数据的时候,提供一个统一的入口,并加上同步锁,

我们需要将提供数据库访问的方法设置成同步的,防止异步调用时出现问题,如:

public static synchronized DBConnection getConnection(String connectionName) throws Exception { String pathFile = getPath() + connectionName;// 转换目录data下 return new DBConnection(SQLiteDatabase.openDatabase(pathFile, null, SQLiteDatabase.OPEN_READWRITE)); }

使用synchronized 关键字来修饰获取数据库连接的方法,或者使用isDbLockedByOtherThreads方法判断数据库是否被锁住了,然后等待一定的时间再进行访问。

或者使用isDbLockedByOtherThreads方法判断数据库是否被锁住了,然后等待一定的时间,并且对于数据库的操作要及时释放,以免多个线程形成死锁

抱歉!评论已关闭.