Ошибка 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. Эти данные были очень большими и занимали кучу памяти. Позаботьтесь о следующем

  1. Удалить Log cat печать больших объемов данных.
  2. Попробуйте использовать только один массив J-SON для всех операций под одним резонансом (используйте его для всех).
  3. Старайтесь избегать использования списка массивов.
  4. Вставьте элемент, когда каждый элемент повторяется из массива J-Son. Это означает, что не следует методу, в котором мы берем элемент как объект и помещаем его в список массивов и передаем список массивов в DB-helper, а затем выполняем итерацию объекта и вставку.

Я верю, что вы можете сделать это так, как вы хотите. Проблема с кодом, который вы разместили, заключается в том, что вы пытаетесь преобразовать весь файл в строку. Я совершенно уверен, что это не получится даже на настольном компьютере.

Я считаю, что вам больше повезет, если вы попытаетесь читать по одной строке за раз и выполнять SQL. Тогда прочитайте следующую строку. Вы также можете уменьшить размер файла, передав его через zip.

Если я найду пару минут, я прикреплю код.

Другие вопросы по тегам