Ошибка Android Out of Memory: как решить эту проблему?
У меня есть приложение, и я пытаюсь настроить в нем довольно большую базу данных SQLite (одну таблицу с примерно 5000 строками). Я создал классы БД и все такое, и мое приложение работает, когда я тестировал в меньшем масштабе (400 строк), но теперь, когда я хочу импортировать свою базу данных, я получаю сообщение об ошибке "Недостаточно памяти", которую, похоже, не могу найти способ обойти.
База данных изначально находится на MySQL на моем веб-сервере, и я не смог преобразовать ее по какой-то странной причине, но мне удалось сгенерировать текстовый файл с запросами, чтобы добавить все 5000 строк, что составляет 11,5 МБ. У меня есть этот файл в папке с активами, и я пытаюсь поместить его в свою БД:
public void onHandleIntent(Intent intent) {
DBAdapter db = new DBAdapter(getApplicationContext());
db.open();
try {
InputStream is = getAssets().open("verbs_sql.txt");
db.executeSQL(convertStreamToString(is));
} catch (IOException e) {}
db.close();
// Run main activity
Intent i = new Intent(DatabaseReceiver.this, BaseActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
DatabaseReceiver.this.startActivity(i);
}
public static String convertStreamToString(InputStream is) throws IOException {
Writer writer = new StringWriter();
char[] buffer = new char[2048];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
String text = writer.toString();
return text;
}
}
Ошибка нехватки памяти возникает в StringWriter(), поэтому похоже, что он помещает этот большой файл в память. Как я могу решить это? Я также попытался перебрать все 5000 строк, но через 30 секунд мне снова не хватило памяти.
4 ответа
Базы данных Sqlite - это просто файлы. Когда вы пытаетесь запустить тысячи вставок на телефоне, вы снова и снова нажимаете на SD-карту для доступа к файлам.
Вам нужно создать базу данных sqlite на рабочем столе и включить уже созданную базу данных в приложение. Если вам нужно регулярно обновлять информацию в базе данных, вы можете разместить ее на веб-сайте и загрузить приложение, просто убедитесь, что вы загружаете только большие объемы через Wi-Fi.
Проверьте эту Техническую беседу для получения дополнительной информации.
Редактировать: см. Это для получения дополнительной информации о создании базы данных sqlite в Windows и включении ее в ваше приложение.
В этом видео от Google:
http://www.youtube.com/watch?v=_CruQY55HOk
Управление памятью описано. Поскольку ваш метод работает в небольшом масштабе, похоже, вы используете больше памяти, чем доступно для вашего приложения.
В видео рассказывается об управлении памятью и о том, как вы можете увеличить размер кучи (верьте, это с Android 4.0 и выше).
У меня такая же проблема. Я пробовал так много способов решить это, но не смог. Наконец я нашел причину и удивился. В моем случае причиной ошибки было то, что я печатал всю строку ответа в журнале cat. Эти данные были очень большими и занимали кучу памяти. Позаботьтесь о следующем
- Удалить Log cat печать больших объемов данных.
- Попробуйте использовать только один массив J-SON для всех операций под одним резонансом (используйте его для всех).
- Старайтесь избегать использования списка массивов.
- Вставьте элемент, когда каждый элемент повторяется из массива J-Son. Это означает, что не следует методу, в котором мы берем элемент как объект и помещаем его в список массивов и передаем список массивов в DB-helper, а затем выполняем итерацию объекта и вставку.
Я верю, что вы можете сделать это так, как вы хотите. Проблема с кодом, который вы разместили, заключается в том, что вы пытаетесь преобразовать весь файл в строку. Я совершенно уверен, что это не получится даже на настольном компьютере.
Я считаю, что вам больше повезет, если вы попытаетесь читать по одной строке за раз и выполнять SQL. Тогда прочитайте следующую строку. Вы также можете уменьшить размер файла, передав его через zip.
Если я найду пару минут, я прикреплю код.