一起使用SQLite可读和可写数据库

时间:2013-05-21 08:02:35

标签: java android sql sqlite

我正在编写Android的代码,该代码同时需要ReadableWritable 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");
}

2 个答案:

答案 0 :(得分:12)

如果您需要读写相同的数据库,我建议您以可写模式打开数据库一次。可写入的数据库也可以读取,因此您可以毫无问题地完成所需的一切。根据{{​​3}},此方法用于

  

创建和/或打开将用于读写的数据库。

因此,无需在两种不同的模式下打开它两次。打开它一次可写,做你需要做的一切,然后关闭它。

答案 1 :(得分:0)

看看你是否想避免这个问题,这里有几件事 一 由于您的数据库有多个连接,因此它们不是序列化的,或者锁定是错误的,因此如果您从多个线程访问数据库并使用不同的连接,那么如果一个线程正在编写它,则锁定db文件和任何将失败的操作帖子 所以要使其工作使用

  1. SQLLite中的WAL模式,您可以在其中进行一次写入操作,并根据线程进行并发读取
  2. 保留单个或单个数据库实例,以便跨多个线程共享的一个连接上的所有操作都被序列化