Android应用冻结SQLite数据库插入

时间:2016-04-18 23:40:11

标签: android database sqlite cursor

我在尝试插入本地数据库时遇到了一个非常奇怪的问题。我将记录添加到2个不同的表中,并且第一次添加它显示在列表中的值,直到活动被销毁。我可以离开并返回并且新的价值就在那里但是当我关闭应用程序并从历史中清除它时它就消失了。

我第二次尝试在数据库中输入一个值时,用户界面冻结,似乎没有任何异常,也没有给我任何关于发生了什么的想法。

这是一些代码。

public void addVehicleService(VehicleService service)
{

    SQLiteDatabase dbWritable = getWritableDatabase();
    int serviceId;
    if (serviceExists(service))
    {
        addServicePerformed(service, null, dbWritable);
    }
    else
    {
        ContentValues values = new ContentValues();
        values.put(VEHICLE_ID, service.getVehicleId());
        values.put(SERVICE_NAME, service.getServiceName());
        values.put(SERVICE_INTERVAL, service.getInterval());
        values.put(SERVICE_MILEAGE, service.getOdometer());
        values.put(DAYS_TO_NEXT_NOTIFICATION, 0);
        values.put(NOTIFIED, 0);
        values.put(INITIAL_NOTIFICATION_DATE, Utility.FormatDate(Calendar.getInstance()));

        serviceId = (int) dbWritable.insert(VEHICLE_SERVICE_TABLE, null, values);
        if (serviceId != -1)
            addServicePerformed(service, serviceId, dbWritable);
        else
            Log.d("DBTAG", "Error inserting new Service");
    }
}


private boolean serviceExists(VehicleService service)
{
    SQLiteDatabase db = getReadableDatabase();

    Cursor cursor = db.query(VEHICLE_SERVICE_TABLE, new String[]{ID}, VEHICLE_ID + " = ? AND " + SERVICE_NAME + " = ? AND " + SERVICE_INTERVAL + " = ?",
            new String[]{service.getVehicleId().toString(), service.getServiceName(), service.getInterval().toString()}, null, null, null);
    int count = cursor.getCount();
    cursor.close();

    return count > 0;
}

private void addServicePerformed(VehicleService service, @Nullable Integer serviceId, SQLiteDatabase dbWritable)
{

    if (serviceId == null)
    {
        dbWritable.beginTransaction();
        serviceId = getServiceId(service, dbWritable);
    }

    ContentValues values = new ContentValues();
    values.put(SERVICE_ID, serviceId);
    values.put(ODOMETER_AT_SERVICE, service.getOdometer());
    values.put(DATE_OF_SERVICE, Utility.FormatDate(service.getDate()));
    values.put(COST_OF_SERVICE, service.getCost());

    dbWritable.insert(SERVICE_PERFORMED_TABLE, null, values);

}

我确实有一些插入数据库的方法,并且保留了更改,因此我对发生的事情感到困惑。

2 个答案:

答案 0 :(得分:1)

首先要注意的是,如果服务存在,您将创建两次SQLiteDatabase的实例。 if(serviceExists(service))

所以我建议不要将dbWritable作为参数传递给

addServicePerformed(service, null, dbWritable);。只需在那里创建一个新实例

private void addServicePerformed(VehicleService service, @Nullable Integer serviceId){
     SQLiteDatabase dbWritable = getWritableDatabase();
}

您的代码中实际发生了什么?

创建一个实例或让我们说方法中的一个对象不会导致任何冻结,因为它的范围将在方法执行完毕后完成,但是全局创建一个实例,然后再次在单独的方法中使用不同的方法实例化并在另一个方法中重用前一个(全局实例)可能导致冻结。不总是,但可能有一段时间。因此,只要您需要创建实例,就不要对它们发生冲突。

答案 1 :(得分:0)

public void addVehicleService(VehicleService service)
{

    int serviceId;
    if (serviceExists(service))
    {
        addServicePerformed(service, null);
    }
    else
    {
        SQLiteDatabase dbWritable = getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(VEHICLE_ID, service.getVehicleId());
        values.put(SERVICE_NAME, service.getServiceName());
        values.put(SERVICE_INTERVAL, service.getInterval());
        values.put(SERVICE_MILEAGE, service.getOdometer());
        values.put(DAYS_TO_NEXT_NOTIFICATION, 0);
        values.put(NOTIFIED, 0);
        values.put(INITIAL_NOTIFICATION_DATE, Utility.FormatDate(Calendar.getInstance()));

        serviceId = (int) dbWritable.insert(VEHICLE_SERVICE_TABLE, null, values);
        if (serviceId != -1)
            addServicePerformed(service, serviceId);
        else
            Log.d("DBTAG", "Error inserting new Service");
    }
}


private void addServicePerformed(VehicleService service, @Nullable Integer serviceId)
{
    SQLiteDatabase dbWritable = getWritableDatabase();

    if (serviceId == null)
    {
        dbWritable.beginTransaction();
        serviceId = getServiceId(service, dbWritable);
    }

    ContentValues values = new ContentValues();
    values.put(SERVICE_ID, serviceId);
    values.put(ODOMETER_AT_SERVICE, service.getOdometer());
    values.put(DATE_OF_SERVICE, Utility.FormatDate(service.getDate()));
    values.put(COST_OF_SERVICE, service.getCost());

    dbWritable.insert(SERVICE_PERFORMED_TABLE, null, values);

}

做@Shree Krishna所说的工作。