Мое приложение синхронизирует свою локальную базу данных SQLite с внешней базой данных, которая существует на серверах Amazon. Иногда синхронизация завершается неудачно и выдает такой вывод logcat:
08-15 19:58:38.149: ERROR/Database(343): Failure 21 (out of memory) on 0x0 when preparing 'drop table if exists keymap2'.
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): Error occurred while syncing DB
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): android.database.sqlite.SQLiteException: unknown error: drop table if exists keymap2
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1610)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at lee.medical.icu.dataentry.db.KeymapDbHelper.syncToTempTable(KeymapDbHelper.java:114)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at lee.medical.icu.dataentry.db.KeymapDbHelper.syncDb(KeymapDbHelper.java:84)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at lee.medical.icu.dataentry.MainMenuActivity$DbSyncTask.doInBackground(MainMenuActivity.java:221)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at lee.medical.icu.dataentry.MainMenuActivity$DbSyncTask.doInBackground(MainMenuActivity.java:1)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at android.os.AsyncTask$2.call(AsyncTask.java:185)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-15 19:58:38.149: ERROR/KeymapDbHelper(343): at java.lang.Thread.run(Thread.java:1096)
Когда это происходит, мое приложение уведомляет меня о сбое синхронизации, поэтому я прошу его снова попытаться выполнить синхронизацию, что работает примерно в 50-75% случаев.
Вот код, который выполняет синхронизацию:
@SuppressWarnings("unchecked")
private void syncToTempTable(SQLiteDatabase db, String table)
throws DatabaseMismatchException {
String awsSql = "select * from " + keymapDb;
SelectRequest select = new SelectRequest(awsSql);
SelectResult result;
Log.d(TAG, "Making request: " + awsSql);
result = simpleDB.select(select); // Could throw AmazonClientException
List<Item> items = result.getItems();
db.execSQL("drop table if exists " + table);
String tempSql = "create table " + table + " (" +
C_KEY + " text primary key, " +
C_NAME + " text)";
db.execSQL(tempSql);
Log.d(TAG, "SQL executed: " + tempSql);
ContentValues cv = new ContentValues();
for (Item i : items) {
cv.clear();
String key = i.getName();
cv.put(C_KEY, key);
List<Attribute> attributes = i.getAttributes();
assert attributes.size() <= 1;
for (Attribute a : attributes) {
String name = a.getName();
String value = a.getValue();
if ((key.equals(R_INFO) && !name.equals(C_REVISION)) ||
(!key.equals(R_INFO) && !name.equals(C_NAME)))
throw new DatabaseMismatchException("DB not synced because " +
"column " + name + " was unexpected");
cv.put(C_NAME, value);
}
db.insert(table, null, cv);
}
}
Строка 114 - db.execSQL("drop table if exists " + table);
Цель этой строки - удалить временную таблицу, если по какой-то причине приложение было аварийно сброшено и предотвратило удаление таблицы, как это обычно происходит. Я заметил, что если эту таблицу оставить в покое, приложение будет зависать при попытке создать новую таблицу с тем же именем.
Почему моему приложению не хватает памяти и что я могу сделать, чтобы это исправить?
Редактировать: Хорошо, это на самом деле происходит каждый раз, когда приложение синхронизируется с внешней базой данных.