Использование SQLite Readable and Writable Database Together

Я пишу код для 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(); } в  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"); } 

Если вам нужно прочитать и написать одну и ту же базу данных, я предлагаю вам открыть базу данных один раз в режиме записи. Считываемую базу данных можно также прочитать, поэтому у вас не должно возникнуть проблемы с выполнением всего, что вам нужно. Согласно документации getWritableDatabase , этот метод используется для

Создайте и / или откройте базу данных, которая будет использоваться для чтения и записи.

Следовательно, нет необходимости открывать его дважды в двух разных режимах. Откройте его один раз как доступный для записи, сделайте все, что вам нужно, затем закройте его.

Посмотрите, хотите ли вы избежать этой проблемы. Здесь есть несколько вещей. Поскольку ваша база данных имеет несколько соединений, они не сериализованы или блокировка не работает, поэтому, если вы получаете доступ к своей базе данных из нескольких потоков и с разными соединениями, поэтому, если один поток записывает блокировки Файл db и любой столбец операций, которые не будут выполнены. Поэтому, чтобы заставить его работать

  1. Режим WAL в SQLLite, в котором вы можете иметь одну операцию записи и одновременное чтение в зависимости от потоков
  2. Храните одноэлементный или один экземпляр БД, поэтому все операции над одним соединением, разделяемым несколькими потоками, сериализуются
Intereting Posts
Android 2.2.1 журнал изменений Как отправить SMS-сообщение в Android Kitkat из приложения, отличного от приложения по умолчанию, без написания SMS-провайдера Как сменить экраны в Scene2D libGDX Ошибка ввода-вывода во время системного вызова, сброс соединения с помощью одноранговой сети Использование собственного сервера XMPP для приложения Android для Android (Smack API) Таблицы с Android-ракурсом на жестком диске Как записывать журнал модема в Android Добавьте android: name = "something" в тег приложения AndroidManifest.xml из Cordova plugin.xml Почему файл .bat пропускает строки и прыгает до конца? Как сделать анимацию справа налево в макете Неизвестная ошибка хрома: -6 Утечка памяти при использовании межстраничных объявлений Admob ActionBar setIcon с Font-Awesome Как сохранить / переупорядочить прослушиватели событий на MapFragment после поворота устройства (портрет / пейзаж)? Удалить значок из searchview в ActionBar