Android SQLite数据库SQLiteDatabaseLockedException处理

Android项目中因为涉及到多线程访问数据库SQLite而出现SQLiteDatabaseLockedException异常,经过查找资料终于找到解决方法:避免数据库接口被多个线程同时访问。

具体措施有:

1、数据库接口采取单例模式

[java] view plain copy

<EMBED id=ZeroClipboardMovie_1 name=ZeroClipboardMovie_1 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=1&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. public synchronized void insert(InstallModel info) {  

  2.     while (db.isDbLockedByOtherThreads() || db.isDbLockedByCurrentThread()){  

  3.         Log.w(Tag, "insert === db is locked by other or current threads!");  

  4.         try {  

  5.             Thread.sleep(10);  

  6.         } catch (InterruptedException e) {  

  7.             e.printStackTrace();  

  8.         }  

  9.     }  

  10.       

  11.     db.execSQL("INSERT INTO install(pkg, pay, install, inApply, flag, attributes, id, introduction, name, smallPicUrl," +  

  12.             "bigPicUrl, categoryId, sourceUrl, pid, cid, built_in, applyMode) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?)",  

  13.             new Object[] {"" + info.getPkg(), "" + info.getPay(), "" + info.getInstall(), "" + info.getIsApply(), "" + info.getFlag(),  

  14.             "" + info.getAttributes(), "" + info.getId(), "" + info.getIntroduction(), "" + info.getName(), "" + info.getSmallPicUrl(),   

  15.             "" + info.getBigPicUrl(), "" + info.getCategoryId(), "" + info.getSourceUrl(), "" + info.getPid(), "" + info.getCid(),   

  16.             "" + info.getBuilt_in(), "" + info.getApplyMode()  

  17.             });  

  18. }  




相关资料:http://www.myexception.cn/sql/419392.html

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabaseLockedException.html

  1. boolean android.database.sqlite.SQLiteDatabase.isDbLockedByOtherThreads();  

  2.   

  3. boolean android.database.sqlite.SQLiteDatabase.isDbLockedByCurrentThread();  



3、光是给接口加锁还不行,因为 synchronized 关键词只能锁定程序块,但是我们真正需要锁的是数据库,好在SQLiteDataBase提供了两个接口,用于检测数据库当时是否被锁定:

所以我们在访问之前还需要增加判断,如果数据库当前被锁定,就等待一会再去访问。

[java] view plain copy

<EMBED id=ZeroClipboardMovie_3 name=ZeroClipboardMovie_3 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=3&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. public class DBOpenHelper extends SQLiteOpenHelper {  

  2.       

  3.     private static final String DB_FILENAME = "llhome.db";  

  4.     private static final int DB_VERSION = 1;  

  5.     private static DBOpenHelper helper = null;  

  6.       

  7.     public static DBOpenHelper getInstance(Context context){  

  8.         if (helper == null){  

  9.             synchronized (DBOpenHelper.class) {  

  10.                 if (helper == null){  

  11.                     DBOpenHelper temp = new DBOpenHelper(context);  

  12.                     helper = temp;  

  13.                 }  

  14.             }  

  15.         }  

  16.           

  17.         return helper;  

  18.     }  


2、所有访问数据的接口用synchronized加锁:

[java] view plain copy

<EMBED id=ZeroClipboardMovie_2 name=ZeroClipboardMovie_2 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=2&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

你可能感兴趣的:(Android SQLite数据库SQLiteDatabaseLockedException处理)