私のSQLiteDatabaseは私にいくつかの問題を与えています。ユーザーがアプリを閉じると、onPause()でAsyncTaskがデータの保存を開始します。これが最善の方法かどうかはわかりませんが、私が行った方法では、最初にデータベースが既存のデータをすべて削除し(それほど多くはなく、2つのテーブル間で20〜30の値になる可能性があります)、次に新しいデータをデータベースに追加し直します。
deleteAll()メソッドは問題なく機能しますが、各アイテムを追加しようとすると、6番目以降は失敗します。
これは、AsyncTaskの私のdoInBackground()メソッドです。
@Override
protected Void doInBackground(Void... args)
{
//open database
try
{
myDbHelper.openDatabase();
}catch(SQLException sqle)
{
throw sqle;
}
myDbHelper.deleteAll();
//add all ingredients & units
for (int i = 0; i < ingredients.size(); i++)
myDbHelper.addIngredient(ingredients.get(i));
for (int i = 0; i < units.size(); i++)
myDbHelper.addUnit(units.get(i));
myDbHelper.close();
return null;
}
次に、DatabaseHelperクラスのdeleteAll()、addIngredient()、およびaddUnit()メソッドを次に示します。
public void deleteAll()
{
int deletedIngredientCount = myDataBase.delete(TABLE_INGREDIENTS, "1", null);
Log.d("QBCPro", deletedIngredientCount + " ingredients deleted successfully");
int deletedUnitCount = myDataBase.delete(TABLE_UNITS, "1", null);
Log.d("QBCPro", deletedUnitCount + " units deleted successfully");
}
public void addIngredient(Ingredient ingredient)
{
ContentValues values = new ContentValues();
values.put(ING_KEY_NAME, ingredient.getName());
values.put(ING_KEY_DENSITY, ingredient.getDensity());
// Insert Row
int row = (int) myDataBase.insert(TABLE_INGREDIENTS, null, values);
if (row == -1)
Log.d("QBCPro", "An error occurred, row == " + row);
else
Log.d("QBCPro", "Successfully inserted " + values.get(ING_KEY_NAME) + " into row " + row);
}
public void addUnit(Unit unit)
{
ContentValues values = new ContentValues();
values.put(UNIT_KEY_NAME, unit.getName());
values.put(UNIT_KEY_BASE_VALUE, unit.getBaseValue());
values.put(UNIT_KEY_FINAL_VALUE, unit.getFinalValue());
values.put(UNIT_KEY_IS_WEIGHT, unit.getIsWeight());
// Insert Row
myDataBase.insert(TABLE_UNITS, null, values);
}
最後に、これがログです。ご覧のとおり、addIngredient()を6回呼び出すだけで、突然終了します。showStatusIconの警告もありますが、それがどこから来ているのか、何が原因なのかわかりません。
02-13 18:47:32.320: D/QBCPro:::(25264): SaveAllTask: Saving to database...
02-13 18:47:32.405: W/IInputConnectionWrapper(25264): showStatusIcon on inactive InputConnection
02-13 18:47:32.445: D/QBCPro(25264): DatabaseHelper deleteAll() called.
02-13 18:47:32.480: D/QBCPro(25264): 11 ingredients deleted successfully
02-13 18:47:32.510: D/QBCPro(25264): 12 units deleted successfully
02-13 18:47:32.510: D/QBCPro(25264): Leaving DatabaseHelper deleteAll() method.
02-13 18:47:32.540: D/QBCPro(25264): Successfully inserted almonds (ground) into row 1
02-13 18:47:32.575: D/QBCPro(25264): Successfully inserted baking powder into row 2
02-13 18:47:32.610: D/QBCPro(25264): Successfully inserted baking soda into row 3
02-13 18:47:32.640: D/QBCPro(25264): Successfully inserted butter into row 4
02-13 18:47:32.685: D/QBCPro(25264): Successfully inserted cocoa powder into row 5
02-13 18:47:32.720: D/QBCPro(25264): Successfully inserted flour (all-purp) into row 6
これがログの終わりであるため、これがメモリリークなどの原因になると思います。また、アプリをフォアグラウンドに戻すと、大量のIInputConnection警告が表示され、すべてのビューが表示されないため、アプリが破損します。
どんな洞察も大歓迎です!
アップデート:
理由もなく発生しなくなりましたが、再開しています。データベース内のコード(ログステートメント以外)は変更していませんが、メインアクティビティを少し変更しましたが、データベースとは関係ありません。何が起こるかです:
ユーザーがアプリを終了すると、AsyncTaskSaveAllTaskが呼び出されます。コードは上記と同じですが、ご覧のとおり、いくつかのログステートメントを追加しました。
02-14 13:41:29.561: D/QBCPro:::(12104): SaveAllTask doInBackground called...
02-14 13:41:29.561: D/QBCPro:::(12104): SaveAllTask: ingredients.size() = 11
02-14 13:41:29.576: D/QBCPro:::(12104): SaveAllTask: units.size() = 12
02-14 13:41:29.616: D/QBCPro:::(12104): SaveAllTask: Saving to database...
02-14 13:41:29.671: W/IInputConnectionWrapper(12104): showStatusIcon on inactive InputConnection
02-14 13:41:29.701: D/QBCPro(12104): DatabaseHelper deleteAll() called.
02-14 13:41:29.736: D/QBCPro(12104): 11 ingredients deleted successfully
02-14 13:41:29.761: D/QBCPro(12104): 12 units deleted successfully
02-14 13:41:29.761: D/QBCPro(12104): Leaving DatabaseHelper deleteAll() method.
02-14 13:41:29.781: D/QBCPro(12104): Successfully inserted almonds (ground) into row 1
02-14 13:41:29.811: D/QBCPro(12104): Successfully inserted baking powder into row 2
02-14 13:41:29.836: D/QBCPro(12104): Successfully inserted baking soda into row 3
02-14 13:41:29.861: D/QBCPro(12104): Successfully inserted butter into row 4
02-14 13:41:29.886: D/QBCPro(12104): Successfully inserted cocoa powder into row 5
02-14 13:41:29.921: D/QBCPro(12104): Successfully inserted flour (all-purp) into row 6
02-14 13:41:29.961: D/QBCPro(12104): Successfully inserted flour (cake) into row 7
02-14 13:41:29.991: D/QBCPro(12104): Successfully inserted milk (2%) into row 8
02-14 13:41:30.021: D/QBCPro(12104): Successfully inserted sugar (br, packed) into row 9
次に、上記のように突然終了しますが、奇妙なことに6行目ではなく9行目です。アプリをフォアグラウンドに戻すと、AsyncTask LoadAllTaskが呼び出され、次のようになります。
02-14 13:43:57.106: D/QBCPro:::(12532): LoadAllTask doInBackground called...
02-14 13:43:57.121: D/QBCPro:::(12532): LoadAllTask: ingredients.size() == 9
02-14 13:43:57.121: D/QBCPro:::(12532): LoadAllTask: units.size() == 0
02-14 13:43:57.121: D/QBCPro(12532): Database CLOSED! (good thing)
02-14 13:43:57.121: D/QBCPro:::(12532): LoadAllTask doInBackground completed...
そして、私のアプリは壊れます。
必要ではないと思いますが、念のため、LoadAllTaskコードを次に示します。
@Override
protected Void doInBackground(Void... params)
{
Log.d(TAG, "LoadAllTask doInBackground called...");
//open database
try
{
myDbHelper.openDatabase();
}catch(SQLException sqle)
{
throw sqle;
}
//get all ingredients and units
ingredients = myDbHelper.getAllIngredients();
units = myDbHelper.getAllUnits();
Log.d(TAG, "LoadAllTask: ingredients.size() == " + ingredients.size());
Log.d(TAG, "LoadAllTask: units.size() == " + units.size());
myDbHelper.close();
Log.d(TAG, "LoadAllTask doInBackground completed...");
return null;
}