Android 数据库的sigleton实例在类中而不是在方法中给出数据库锁定异常
当我在类中使用singleton数据库对象时,我遇到了一个问题,在类中我得到了数据库锁定异常,但是当我在同一类的任何方法中使用相同的对象时,一切都很好,我对行为感到困惑。下面是代码:数据库类:具有单例功能Android 数据库的sigleton实例在类中而不是在方法中给出数据库锁定异常,android,singleton,android-sqlite,database-locking,Android,Singleton,Android Sqlite,Database Locking,当我在类中使用singleton数据库对象时,我遇到了一个问题,在类中我得到了数据库锁定异常,但是当我在同一类的任何方法中使用相同的对象时,一切都很好,我对行为感到困惑。下面是代码:数据库类:具有单例功能 public class Database extends SQLiteOpenHelper{ private static String dbname="Director"; private static int dbversion=1;
public class Database extends SQLiteOpenHelper{
private static String dbname="Director";
private static int dbversion=1;
SQLiteDatabase db;
private Context m1Context;
private static Database minstance;
public Database(Context context) {
super(context, dbname, null, dbversion);
// TODO Auto-generated constructor stub
}
public synchronized static Database getInstance(Context m1Context){
if (minstance==null){
minstance=new Database(m1Context);
}
return minstance;
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
STable st=new StockTable(m1Context);
BTable bt=new BrokerageTable(m1Context);
SList sl=new StockList(m1Context);
db.execSQL(st.stocktable);
db.execSQL(bt.Brokerage);
db.execSQL(sl.Create());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
现在,当我在多个类中使用singleton实例时,只有当它在类内声明,而不是在同一类的方法内声明时,才会锁定错误数据库。在下面的代码行中,astrik和加号之间的代码行给出了类内的错误,加号和加号之间的代码行并没有给出错误,但我在这两种情况下都做了相同的处理
public class SList {
Context c1;
Cursor getid;
StockList(Context mContext){
c1=mContext;
}
**//SQLiteDatabase sd=Database.getInstance(c1).getWritableDatabase();**
String Ctable;
//String ,selectIDgetstocks,deletestock;
public String tablename="Stocklist";
public String Column1="_id";
public String Column2="Sname";
ContentValues cv=new ContentValues();
String getstocks="Select " + Column1 + " as _id, " + Column2 + " From "+ tablename;
String selectID="Select Max("+ Column1 + ") from " + tablename;
public String Create(){
Ctable="Create Table " + tablename + " (" + Column1 + " INTEGER PRIMARY KEY , " + Column2 + " Text" + ")";
return Ctable;
}
public void insert(int stockid,String name){
cv.put(Column1, stockid);
cv.put(Column2, name);
++Database.getInstance(c1).getWritableDatabase().insert(tablename,null,cv);++
}
}
有人能帮我澄清一下我的困惑吗?如果可能的话,让我知道单例使用的功能。我的想法是在类开始时在数据库变量中使用sigleton实例,并在整个类中需要的地方使用该变量,但这是不可能的,不知道为什么,但当我在所有位置使用同一实例时,则不会出错
请帮助我理解。如果您使用数据库,请使用此
String query = "select * from table1";
synchronized(Database.getInstance(c1) )
{
db = Database.getInstance(c1).getWritableDatabase();
Cursor c = db.rawQuery( query );
c.moveToFirst();
do
{
// do someting use database.
Log.d( SList.class.getName(), c.getString( 0 ) );
}while( c.moveToNext() );
c.close();
db.close();
}
如果使用完db,是否调用db close?若你们得到Instance调用GetWritableDatabase,另一个地方同时调用GetWritableDatabase,你们可能会得到错误。实例,即getWratableDatabase,您稍后调用,并提前关闭。感谢您的回复。。。我没有调用db.close,但我有5个活动,在所有活动中,我需要getwritabledatabase实例。。。但是在这种情况下,我如何实现功能,以及我应该在哪里调用db.close,就好像在一个活动数据库使用完成后,另一个活动数据库使用开始一样。对不起,我不太清楚您的问题。现在,我明白了。很简单。你只需要使用synchronized。本页的答案是“帮助您”。[链接]Singleton与synchronized不同。单例模式只是生成一个实例,比如static(但它有些不同)。synchronized是多线程中的安全实例。它是做相同的函数互斥或信号量(但显然不一样。)感谢链接,但为什么我在类的开头声明它会给我错误,在语句中使用它不会给我数据库锁定异常?另外,请您解释如何以及何时关闭数据库对象。谢谢您的回答。。这里我有一个问题
Database.getInstance(c1).getWritableDatabase()代码>如果我对多个查询(如insert、select、delete)多次使用此语句,会对数据库产生任何影响吗?。还需要在每次操作(插入、选择或删除)后关闭数据库…感谢您的持续协助,只要数据发生更改(插入或删除),它就会对数据库产生影响。如果你想及时进行多次手术,只需在手术结束后进行。如果使用游标,请在使用完游标后关闭数据库。您可以在android sqlite3中使用事务。如果您想要交易,此链接将帮助您。[链接]如果您这样做,它可能是一个例外。首先,插入数据。其次,使用execSql选择并连接游标。第三,从数据库中删除数据wehre在游标中。然后,当您第二次得到游标时,使用游标的数据(getString、getInt等),它可能是异常的。游标不是用来存储数据的。只是连接数据库的数据。对不起,我的英语不是很好,所以我的答案很难理解。但我试着解释我所知道的。没问题@Amadas。。。你确实帮助了我。。。一旦我在代码中实现您的建议,我将接受答案。