原文  http://www.cnblogs.com/wangmars/p/4530670.html

在开发Android的程序的时候sqlite数据库是经常用到的;在多线程访问数据库的时候会出现这样的异常: java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed . 或 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase : 或 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

这样的异常信息,Sqlite 自身是不支持多线程同时操作的,下面呢我们给出一个解决方案并列出一些项目中用到的代码。

我们会用到AtomicInteger,一个提供原子操作的Integer的类。因为Android 依托强大的jdk在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口,由此我们可以做一个DatabaseManager 这样的类,具体代码见下面的代码块:

public class DatabaseManager {  private AtomicInteger mOpenCounter = new AtomicInteger();  private static DatabaseManager instance;    private static SQLiteOpenHelper mDatabaseHelper;    private SQLiteDatabase mDatabase;   public static synchronized void initializeInstance(SQLiteOpenHelper helper) {      if (instance == null) {        instance = new DatabaseManager();        mDatabaseHelper = helper;      }    }    public static synchronized DatabaseManager getInstance(SQLiteOpenHelper helper) {      if (instance == null) {        initializeInstance(helper);    }      return instance;    }    public synchronized SQLiteDatabase getWritableDatabase() {      if(mOpenCounter.incrementAndGet() == 1) {        // Opening new database        mDatabase = mDatabaseHelper.getWritableDatabase();      }      return mDatabase;    }    public synchronized SQLiteDatabase getReadableDatabase() {      if(mOpenCounter.incrementAndGet() == 1) {        // Opening new database        mDatabase = mDatabaseHelper.getReadableDatabase();      }      return mDatabase;    }    public synchronized void closeDatabase() {      if(mOpenCounter.decrementAndGet() == 0) {        // Closing database        mDatabase.close();      }    }

在我们进行关闭数据库的时候判断

mOpenCounter.decrementAndGet() == 0 (更新器管理的给定对象的字段的当前值为0)的时候才正式关闭数据库,就不会出现上述异常。用方式呢,在我们操作数据库逻辑代码中如下使用首相要取得
mDatabaseManager = DatabaseManager.getInstance(mContext);
对象
/*** * 判断表中是否有值 */public boolean isExistTabValus() {  boolean flag = false;  SQLiteDatabase db = mDatabaseManager.getReadableDatabase();//获取一个可读的数据库对象  Cursor curcor = null;  try {    curcor = db.rawQuery("select * from tab ", null);    while (curcor.moveToNext()) {      if (curcor.getCount() > 0) {        flag = true;      }    }  } catch (Exception e) {    Log.e(TAG, "isExistTabValus  error");  } finally {    if (curcor != null) {      curcor.close();    }    mDatabaseManager.closeDatabase();//关闭数据库  }  return flag;}

上面提供一个使用方法,现在项目中使用这种方法关于数据库的操作从未没有出现并发的问题,大家可以尝试一下。


更多相关文章

  1. android操作系统默认的图片
  2. Android(安卓)-很全的android操作内容丰富
  3. 这些年正Android(安卓)- 大纲
  4. android UI跨线程操作
  5. 【Android(安卓)文件管理】分区存储 ( MediaStore 文件操作 )
  6. 系出名门Android(9) - 数据库支持(SQLite), 内容提供器(ContentP
  7. Afinal 是一个android的sqlite orm 和 ioc 框架。同时封装了andr
  8. 如何查看android数据文件?
  9. android客户端和servlet服务端的简单登录实现

随机推荐

  1. Android中Activity启动模式详解
  2. android用sharepreference保存输入框中的
  3. eclipse中安装android ADT插件及无法下载
  4. Android(安卓)经典小技巧总结
  5. Android获取当前网络状态和获取当前设备
  6. 【Android】Android6.0发送短信Demo
  7. android判断当前网络状态,eth wifi pppoe
  8. GMS Android(安卓)Q移除launcher3 google
  9. Android——4.2.2 源码目录结构分析
  10. MMS PDU