我正在处理的应用程序最初将有一个带有表的数据库,比如tbl_usr
,它只有一个记录。基本上我们试图保持每个设备一个用户。当用户使用身份验证代码从设备登录时,他的详细信息将从服务器获取并存储在数据库中。下次如果他试图输入不同的验证码,这是有效的但不在表中,那么他将不被允许继续。以下是常见的DBHelper
类。
但无论采用什么方法,我都会在第二次登录时尝试 databaselocked 异常。我已经提到了各种链接,其中建议在方法中使用database
的不同实例,但它仍然带有错误。以下是我的助手课程
public class DBaseHelper extends SQLiteOpenHelper {
private static String CREATE_TABLE;
private static final String DATABASE_NAME="IPDB";
private static String UserMessage="";
private int tableType=0;
private ContentValues cValues;
private Cursor cursor;
public enum TableTypes{
Table1
};
public DBaseHelper(Context context){
super(context,context.getExternalFilesDir(null).getAbsolutePath()+"/"+DATABASE_NAME,null,1);
}
@Override
public void onCreate(SQLiteDatabase db){
TableTypes tableTypes=TableTypes.values()[tableType];
switch (tableTypes){
case Table1:
CREATE_TABLE="CREATE TABLE IF NOT EXISTS tbl_usr....";
break;
default:
break;
}
db.execSQL(CREATE_TABLE);
db.close();
System.out
.println("onCreate Method Done.");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
/*db.execSQL("DROP TABLE IF EXISTS "+LOGIN_TABLE);*/
onCreate(db);
}
/*this is the method which gets called from other class Like*/
/*helper.insertRecord(tableParams);*/
public HashMap<String,String> insertRecord(HashMap<String,String> dbaseParams){
HashMap<String,String> response=new HashMap<String,String>();
tableType=Integer.parseInt(dbaseParams.get("tableType"));
cValues = new ContentValues();
String TableName="";
TableTypes tableTypes=TableTypes.values()[tableType];
switch (tableTypes){
case Table1:
String AuthCode=dbParams.get("AuthCode");
/*if user exists then check if its the same user*/
if( CheckUserRecordExists(AuthCode) && empty(UserMessage) ){
response.put("isSuccess","true");
return response;
}
else {
if (!empty(UserMessage)) {
response.put("isSuccess", "false");
response.put("message",UserMessage);
return response;
}
/*add new user
Fill cValues declared above*/
TableName = "Table1";
}
break;
default:
break;
}
SQLiteDatabase dataBase = getWritableDatabase();
/*insert data into database*/
try {
dataBase.beginTransaction();
long rowID = dataBase.insertOrThrow(TableName, null, cValues);
dataBase.setTransactionSuccessful();
}
catch(Exception ex){
ex.printStackTrace();
}
finally {
dataBase.close();
}
response.put("isSuccess", "true");
return response;
}
private boolean CheckUserRecordExists(String authCode){
UserMessage="";
SQLiteDatabase dataBase=getReadableDatabase();
/*Exception here when comes for 2nd time after new installation*/
cursor = dataBase.query("Table1", new String[]{"COUNT(*)"}, null, null, null, null, null);
cursor.moveToFirst();
int iCount=cursor.getInt(0);
/*check if any record exist*/
if(iCount>0){
dataBase.close();
if(!cursor.isClosed()) cursor.close();
/*check if the code entered matches with the record existing*/
if(!CheckIsDataAlreadyInDBorNot("Table1","Auth_Code",authCode))
{
UserMessage="Invalid login!";
return false;
}
else return true;
}
else{
dataBase.close();
if(!cursor.isClosed()) cursor.close();
return false;
}
}
private boolean CheckIsDataAlreadyInDBorNot( String TableName,
String dbfield, String fieldValue) {
/*checking if user is same user*/
SQLiteDatabase dataBase=getReadableDatabase();
String[] columns = { dbfield };
String selection = dbfield + " =?";
String[] selectionArgs = { fieldValue };
String limit = "1";
Cursor cursor = dataBase.query(TableName, columns, selection, selectionArgs, null, null, null, limit);
boolean exists = (cursor.getCount() > 0);
cursor.close();
dataBase.close();
return exists;
}
public static boolean empty( final String s ) {
return s == null || s.trim().isEmpty();
}
}
我知道它的代码很庞大,但逻辑很简单。但问题是数据库锁定。有人能让我知道如何确保数据库在每次操作时始终处于有效状态吗?
答案 0 :(得分:1)
您有beginTransaction()
但没有与endTransaction()
匹配的来电。正在进行的事务使数据库保持锁定状态,并使内部引用计数保持非零,因此close()
尚未实际关闭数据库。
交易操作的传统模式是
db.beginTransaction();
try {
// db operations that can throw
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
同样在您的onCreate()
中,您不应该关闭数据库,因为您不拥有它。