2016-04-18 19 views
1

ローカルデータベースに挿入しようとすると、本当に奇妙な問題が発生しています。私は2つの異なるテーブルにレコードを追加しています。アクティビティが破棄されるまで、リストに表示される値を最初に追加します。私は離れて戻って来ることができ、新しい価値がそこにあるが、私はアプリを閉じて、歴史からそれをクリアすると、それはなくなった。SQLite db insertでAndroidアプリがフリーズする

2回目にデータベースに値を入力しようとすると、UIがフリーズし、例外がスローされたり、何が起こっているのかわからないようです。

ここにいくつかのコードがあります。

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); 

} 

データベースに挿入するメソッドがあり、変更が保持されているため、何が起こっているのか本当に混乱しています。

+0

多分、バックグラウンドのスレッド/ハンドラに作業をオフロードしようとしますか? – Submersed

+0

@Submersed私が数分間待っても、応答しないアプリケーションを投げることはありませんが、私はnotifcation barとすべてを引き下げることができます。それは最終的にuiスレッドから移動されますが、挿入の2行です。最悪の場合でも1秒以上かかることはありません – Stampede10343

+1

'addServicePerformed(service、null、dbWritable);でdbWritableを渡してみてください。 'addServicePerformed'にSqlitedatabaseの別のインスタンスを作成するだけです。そして、この行 'SQLiteDatabase dbWritable = getWritableDatabase();'をelseに移動します。 –

答えて

1

最初に気付くべきことは、サービスが存在する場合にインスタンスSQLiteDatabaseを2回作成することです。 if(serviceExists(service))

だから私は

addServicePerformed(service, null, dbWritable);にパラメータとして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が言ったことをやっていること。

関連する問題