我正在编写Android
的代码,该代码同时需要Readable
和Writable
Database
。我收到了以下错误:
05-21 13:27:47.079: E/SQLiteDatabase(8326): close() was never explicitly called on database '/data/data/com.example.devicecontrolpanel/databases/AlarmSystem'
05-21 13:27:47.079: E/SQLiteDatabase(8326): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:2052)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1087)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1050)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1136)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1041)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:165)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at com.example.devicecontrolpanel.DataBaseAdapter.addDeviceOnSearch(DataBaseAdapter.java:215)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at com.connection.DeviceInformation.<init>(DeviceInformation.java:39)
05-21 13:27:47.079: E/SQLiteDatabase(8326): at com.example.devicecontrolpanel.TestActivity$DeviceSearcher$3.run(TestActivity.java:251)
这段代码制作错误,正如我猜测的那样:
public int addDeviceOnSearch(DeviceInformation device) //Final and done
{
SQLiteDatabase dbRead = this.getReadableDatabase();
String[] columDevice = {DEVICE_ID, DEVICE_NAME, DEVICE_IP, DEVICE_TYPE};
String[] columPin = {PIN_ID, PIN_NO, PIN_NAME, PIN_CURRENT_STATUS};
Cursor cursorDevice = dbRead.query(DEVICE_TABLE, columDevice, DEVICE_MAC+"=?", new String[] {device.getMAC()}, null, null, null);
dbRead.close();
if(cursorDevice==null)
{
SQLiteDatabase dbWrite = this.getWritableDatabase();
ContentValues values = new ContentValues();
//New Device
values.put(DEVICE_IP, device.getIP());
values.put(DEVICE_MAC, device.getMAC());
values.put(DEVICE_NAME, device.getDeviceName());
values.put(DEVICE_TYPE, device.getType());
long devId = dbWrite.insert(DEVICE_TABLE, null, values);
device.setId((int) devId);
dbWrite.close();
}
else
{
此行第215行出错
SQLiteDatabase dbWrite = this.getWritableDatabase();
此行第215行出错
ContentValues values = new ContentValues();
//Already Exist
device.setId(Integer.parseInt(cursorDevice.getString(0)));
device.setDeviceName(cursorDevice.getString(1));
values.put(DEVICE_IP, device.getIP());
values.put(DEVICE_TYPE, device.getType());
dbWrite.update(DEVICE_TABLE,values, DEVICE_ID+ " = ?",new String[] {String.valueOf(device.getId())});
values = new ContentValues();
dbWrite.close();
dbRead = this.getReadableDatabase();
Cursor cursorPin = dbRead.query(PIN_TABLE, columPin, PIN_DEVICE_ID+"=?", new String[] {String.valueOf(device.getId())}, null, null, null);
if(cursorPin==null)
{
device.setDevicePin(null);
}
else
{
cursorPin.moveToFirst();
List<DevicePinDetail> devicePins = new ArrayList<DevicePinDetail>();
do
{
int pinId=Integer.parseInt(cursorPin.getString(0));
int pin_no=Integer.parseInt(cursorPin.getString(1));
String PinName =cursorPin.getString(2);
int pinStatus=Integer.parseInt(cursorPin.getString(3));
int PinDeviceId=device.getId();
devicePins.add(new DevicePinDetail(pinId, pin_no, PinName, PinDeviceId, pinStatus));
}while(cursorPin.moveToNext());
device.setDevicePin(devicePins);
}
}
dbRead.close();
return device.getId();
}
的onCreate()
@Override
public void onCreate(SQLiteDatabase db)
{
String CREATE_ALARM_TABLE = "Create Table "+TABLE_NAME+"("
+KEY_ALARM_ID+" integer primary key AUTOINCREMENT, "+KEY_DESC+" TEXT, "+KEY_REPEAT_DAY+ " TEXT,"
+KEY_REPEAT_TYPE+" integer, "+KEY_CALENDAR+" TEXT, "+KEY_DEVICE_MAC+" TEXT,"+KEY_DEVICE_IP+" TEXT,"
+KEY_DEVICE_TYPE+" integer, "+KEY_JSON+" TEXT,"+KEY_ACTIVE+" integer, "+KEY_DEVICE_NAME+" text);";
String CREATE_DEVICE_TABLE = "Create Table "+ DEVICE_TABLE+"("
+DEVICE_ID+" integer primary key AUTOINCREMENT, "+DEVICE_MAC+" TEXT, "+DEVICE_NAME+" text, "+DEVICE_IP+" TEXT,"+DEVICE_TYPE+" integer);";
String CREATE_PIN_TABLE = "Create Table "+ PIN_TABLE + "("
+PIN_ID+" integer primary key AUTOINCREMENT, "+PIN_NO+" integer, "+PIN_NAME+" text, "+PIN_CURRENT_STATUS+" integer, "
+PIN_DEVICE_ID+" integer);";
String CREATE_SETTING_TABLE = "Create Table "+SETTINGS_TABLE+" ("
+SETTINGS_ID+" integer primary key AUTOINCREMENT, "
+SETTINGS_COMPUTER+" integer, "+SETTINGS_RASPBERRY+ " integer, "+SETTINGS_FLYPORT+ " integer,"
+COMPUTER_IP + " text,"+COMPUTER_PORT_SEND+" integer, "+RASPBERRY_IP+" text,"+RASPBERRY_PORT_SEND+" integer,"
+ " text,"+COMPUTER_PORT_RECV+" integer,"+RASPBERRY_PORT_RECV+" integer);";
db.execSQL(CREATE_PIN_TABLE);
db.execSQL(CREATE_ALARM_TABLE);
db.execSQL(CREATE_DEVICE_TABLE);
db.execSQL(CREATE_SETTING_TABLE);
ContentValues values = new ContentValues();
values.put(SETTINGS_COMPUTER, 1);
values.put(SETTINGS_RASPBERRY, 1);
values.put(SETTINGS_FLYPORT, 1);
values.put(COMPUTER_IP, "225.4.5.6");
values.put(RASPBERRY_IP, "225.4.5.6");
values.put(COMPUTER_PORT_SEND, 5000);
values.put(COMPUTER_PORT_RECV, 5003);
values.put(RASPBERRY_PORT_SEND, 6000);
values.put(RASPBERRY_PORT_RECV, 6003);
db.insert(SETTINGS_TABLE, null, values);
System.out.println("Values added");
}
答案 0 :(得分:12)
如果您需要读写相同的数据库,我建议您以可写模式打开数据库一次。可写入的数据库也可以读取,因此您可以毫无问题地完成所需的一切。根据{{3}},此方法用于
创建和/或打开将用于读写的数据库。
因此,无需在两种不同的模式下打开它两次。打开它一次可写,做你需要做的一切,然后关闭它。
答案 1 :(得分:0)
看看你是否想避免这个问题,这里有几件事 一 由于您的数据库有多个连接,因此它们不是序列化的,或者锁定是错误的,因此如果您从多个线程访问数据库并使用不同的连接,那么如果一个线程正在编写它,则锁定db文件和任何将失败的操作帖子 所以要使其工作使用