大佬教程收集整理的这篇文章主要介绍了Android上的SQLite数据库,多线程,锁定和帐户同步,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个使用数据库的应用程序,还有Android帐户和Android同步来同步我的应用程序的数据.我的猜测是,当两者同时发生时,它会崩溃.我遇到了很多错误:
* android.database.sqlite.sqliteDatabaseLockedException: database is locked * android.database.sqlite.sqliteDatabaseLockedException: database is locked (code 5) * android.database.sqlite.sqliteDatabaseLockedException: error code 5: database is locked * android.database.sqlite.sqliteDatabaseLockedException: database is locked (code 5):,while compiling: PRAGMA journal_mode * android.database.sqlite.sqliteDiskIOException: disk I/O error (code 778) * android.database.sqlite.sqliteException: Failed to change locale for db '/data/data/net.bicou.redmine/databases/redmine.db' to 'en_US'. \n Caused by: android.database.sqlite.sqliteDatabaseLockedException: database is locked (code 5)
我有的是:
>一个抽象基类,DbAdapter,由想要管理单个表的子类扩展
>一个管理sqlite数据库的类,名为DbManager,包含一个Lock
现在,用户有一个不是单身的DbManager版本.我打算让DbManager成为单例,以便所有线程共享同一个对象.这不应该是一个问题,因为据我所知,后台同步和应用程序共享相同的过程.
这是课程(只有相关部分):
public abstract class DbAdapter { Context mContext; protected DbManager mDbManager; sqliteDatabase mDb; public static final String KEY_ROWID = "_id"; public DbAdapter(final Context ctX) { mContext = ctx; } public DbAdapter(final DbAdapter other) { mContext = other.mContext; mDb = other.mDb; mDbManager = other.mDbManager; // removed with singleton version } public synchronized DbAdapter open() throws sqlException { if (mDb != null) { return this; } mDbManager = new DbManager(mContext); // currently in production mDbManager = DbManager.instance(mContext); // currently investigaTing this singleton solution try { mDb = mDbManager.getWritableDatabase(); } catch (final sqlException E) { l.e("Unable to open DB,trying again in 1 second",E); try { Thread.sleep(1000); } catch (final InterruptedException e1) { l.e("Could not wait 1 second " + e1); } mDb = mDbManager.getWritableDatabase();// This may crash } return this; } public synchronized void close() { mDbManager.close(); mDbManager = null; mDb = null; } }
需要处理数据库表的类将扩展DbAdapter,并实现SELEct,insert,delete等方法.
public class DbManager extends sqliteOpenHelper { private static final String DB_FILE = "db"; private static final int DB_VERSION = 15; Context mContext; Lock mLock = new reentrantlock(); // Currently in prod public DbManager(final Context context) { super(context,DB_FILE,null,DB_VERSION); mContext = context; } // singleton version will make this constructor private and add: private static DbManager mInstance; public static synchronized DbManager instance(Context context) { if (instance == null) { instance = new DbManager(context); } return instance; } @Override public sqliteDatabase getWritableDatabase() { mLock.lock(); return super.getWritableDatabase(); } @Override public void close() { super.close(); mLock.unlock(); } @Override public void onCreate(final sqliteDatabase db) { // ... } @Override public void onUpgrade(final sqliteDatabase db,final int oldVersion,final int newVersion) { // ... } private void createTables(final sqliteDatabase db,final String[] statements) { for (final String sql : statements) { try { db.execsql(sql); } catch (final Exception E) { l.e("Unable to create table: " + sql,E); } } } }
好的,现在,问题.
>我的锁是否正确实施?我真的很陌生,我不知道reentrantlock是不是一个好选择,如果我在适当的时候锁定/解锁
>我的同步方法是否正确实施?我的意思是,我已将synchronized关键字放在我不希望被并发线程中断的方法周围.这是正确的吗?你可以就我的同步使用提出建议吗?
>我该如何重现这个问题?我创建了一个测试,它使用3个线程对数据库进行并发读/写访问,并使用一些Thread.sleep来确保每个线程的db打开/关闭重叠,但它不会崩溃.这真是烦我,我不认为有很多人有这个问题,所以我不知道如何重现.
>我的DbAdapter DbManager技术选择是个好主意吗?有更好的模式吗?
>让DbManager成为单身人士是个好主意吗?
但是,在插入上有一些NullPointerExceptions并非不可能.因此,要扩展“Thread.sleep”逻辑,可以使用以下代码:
@Override public sqliteDatabase getWritableDatabase() { while (true) { try { return super.getWritableDatabase(); } catch (sqliteDatabaseLockedException E) { System.err.println(E); } try { Thread.sleep(500); } catch (InterruptedException E) { System.err.println(E); } } }
以上是大佬教程为你收集整理的Android上的SQLite数据库,多线程,锁定和帐户同步全部内容,希望文章能够帮你解决Android上的SQLite数据库,多线程,锁定和帐户同步所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。