db.delete() Error处理:java.lang.IllegalStateException: databases already closed

Android Error处理:java.lang.IllegalStateException: databases  already closed


今天导入一个基于Android 2.x版本SDK项目,运行的时候一直出错,错误如下:

11-18 16:58:56.595:E/AndroidRuntime(22991): java.lang.RuntimeException: Unable to start servicexxx.xxxx.service.LocalService@41985638 with Intent {act=xxx.xxx.xxx.APP_SERVICE (has extras) }: java.lang.IllegalStateException:database /data/data/xxx.xxx.xxx/databases/xxx.db (conn# 0) already closed


判断可能是数据库操作部分出了问题,数据库操作部分文件代码DBHelper.java如下:

[java]  view plain copy
  1. package org.yousee.utils;  
  2.   
  3.   
  4. import android.content.ContentValues;  
  5. import android.content.Context;  
  6. import android.database.Cursor;  
  7. import android.database.sqlite.SQLiteDatabase;  
  8. import android.database.sqlite.SQLiteOpenHelper;  
  9. import android.database.sqlite.SQLiteDatabase.CursorFactory;  
  10. /** 
  11.  * 存储记录的数据库 
  12.  */  
  13. public class DBHelper extends SQLiteOpenHelper {  
  14.     private Cursor c = null;  
  15.     private static final String CREATE_TAB = "create table "  
  16.         + "music(_id integer primary key autoincrement,music_id integer,clicks integer," + "latest text)";  
  17.     private static final String TAB_NAME = "list";  
  18.     private SQLiteDatabase db = null;  
  19.     public DBHelper(Context context, String name, CursorFactory factory,int version) {  
  20.         super(context, name, factory, version);  
  21.     }  
  22.   
  23.     @Override  
  24.     public void onCreate(SQLiteDatabase db) {  
  25.         this.db = db;  
  26.         db.execSQL(CREATE_TAB);  
  27.     }  
  28.       
  29.     public void insert(ContentValues values){  
  30.         SQLiteDatabase db = this.getWritableDatabase();  
  31.         db.insert(TAB_NAME, null, values);  
  32.         db.close();//应改为this.close()  
  33.     }  
  34.   
  35.     public void update(ContentValues values,int id){  
  36.         SQLiteDatabase db = this.getWritableDatabase();  
  37.         db.update(TAB_NAME, values, "music_id="+id, null);  
  38.         db.close();//应改为this.close()  
  39.   
  40.     }  
  41.       
  42.     public void delete(int id){  
  43.         if (db == null){  
  44.             db = getWritableDatabase();  
  45.         }  
  46.         db.delete(TAB_NAME, "music_id=?"new String[]{String.valueOf(id)});  
  47.     }  
  48.       
  49.     public Cursor query(int id){  
  50.         SQLiteDatabase db = getReadableDatabase();  
  51.         c = db.query(TAB_NAME, null"music_id=?"new String[]{String.valueOf(id)}, nullnullnull);  
  52.         db.close();//应改为this.close()  
  53.   
  54.         return c;  
  55.     }  
  56.       
  57.     public Cursor queryByClicks(){//按点击量查询  
  58.         SQLiteDatabase db = getReadableDatabase();  
  59.         c = db.query(TAB_NAME, nullnullnullnullnull"clicks desc");  
  60.         return c;  
  61.     }  
  62.       
  63.     public Cursor queryRecently(){//按时间降序查询  
  64.         SQLiteDatabase db = getReadableDatabase();  
  65.         c = db.query(TAB_NAME, nullnullnullnullnull"latest desc");  
  66.         return c;  
  67.     }  
  68.       
  69.     public void close(){  
  70.         if (db != null){  
  71.             db.close();//应改为this.close()  
  72.   
  73.             db=null;  
  74.         }  
  75.         if (c!=null){  
  76.             c.close();  
  77.             c=null;  
  78.         }  
  79.     }  
  80.       
  81.     @Override  
  82.     public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {  
  83.   
  84.     }  
  85.   
  86. }  
经过 分析发现是关闭数据库时直接调用了SQLiteDatabase.close()方法。


出错的具体原因为:

如果调用SQLiteDatabase.close()代替SQLiteOpenHelper.close()。那么SQLiteOpenHelper就不知道通过helper获取的DB是否是关闭的(getReadableDatabase或getWritableDatabase)。

总结:

1、SQLiteOpenHelper.close()是异步的,而SQLiteDatabase.close()不是。

2、在使用安卓提供的SQLiteOpenHelper时,通过getReadableDatabase或getWritableDatabase获得的其实是同一个对象,唯一的却别就是如果你的硬盘不足了,那么你就不能在调用getWritableDatabase,只能调用getReadableDatabase。

3、使用Android提供的数据库接口进行数据库操作的时候一定要遵循Andoid的规则。在多线程中要注意,所以养成好的面向对象的习惯,调用helper的close方法关闭数据库。(谁提供的数据,就调用谁的方法来操作数据)



网上还看到有类似的问题:

http://androiddev.orkitra.com/?p=30756

http://stackoverflow.com/questions/6535908/android-sqlite-sqliteopenhelper-error-illegalstateexception-db-already-clo



转自:http://blog.csdn.net/netwalk/article/details/16808897

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值