Android-ресурсы GC выпуск - PullRequest
0 голосов
/ 19 ноября 2018

Я использую

Drawable drawable = res.getDrawable(id);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(bitmap);
bitmap.eraseColor(0);
drawable.setBounds(0,0, width, height);
drawable.draw(canvas);
return load(bitmap, linear);

для загрузки отрисовки из идентификатора ресурса в OpenGL с заданной шириной и высотой. (Использование

android.opengl.GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);

) Функция load выполняет GL-вызовы, а также вызывает bitmap.recycle ().

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

Теперь моя проблема (эта часть работает нормально): если я запускаю свое приложение в первый раз из Android Studio, все работает; ОДНАКО, если я хочу перезапустить его, он падает из-за OutOfMemoryError. Я делаю одинаковые звонки в обоих случаях.

Я обнаружил, что проблема заключается в управлении ресурсами Android, как вы можете видеть из анализа кучи: мои самые дорогие ассигнования

Размер моих изображений в натуральном выражении меньше 9 МБ (512x512, RGBA, поэтому 1 МБ). Как я могу запретить Android хранить эти большие байтовые массивы, которые, вероятно, подразумеваются как некий кеш; который, однако, не запускается при первом запуске после установки приложения?

Я тестирую на Android 6.0.1, API версии 23, Galaxy S5.

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Я решил это (сам), поместив файлы в папку raw каталога ресурсов и загрузив их, используя

fun loadBitmap(res: Resources, rawId: Int): Bitmap {
    val inputStream = BufferedInputStream(res.openRawResource(rawId))
    return BitmapFactory.decodeStream(inputStream)
}

, а затем позвонив

load(bitmap, linear);

и

bitmap.recycle()

как раньше. К счастью, это были файлы png / jpeg, поэтому мне не нужны были дополнительные функции папки drawables. Используя это, они автоматически используют правильное разрешение.

Мое выделение памяти Java теперь восстановлено на 25–35 МБ вместо 110 МБ при использовании старого способа:).

0 голосов
/ 19 ноября 2018

Реализация texImage2D выглядит так:

public static void texImage2D(int target, int level, int internalformat,
        Bitmap bitmap, int border) {
    if (bitmap == null) {
        throw new NullPointerException("texImage2D can't be used with a null Bitmap");
    }
    if (bitmap.isRecycled()) {
        throw new IllegalArgumentException("bitmap is recycled");
    }
    if (native_texImage2D(target, level, internalformat, bitmap, -1, border)!=0) {
        throw new IllegalArgumentException("invalid Bitmap format");
    }
}

Не похоже, что это что-то перерабатывает. Вы уверены, что не загружаете огромное растровое изображение в память? Двух этих вызовов более чем достаточно, чтобы гарантировать огромный взрыв в вашем приложении, если не один (я видел, как это происходило много раз в моем приложении). Помните, перезапуск вашей деятельности не означает перезапуск вашего процесса.

Запустите Android Profiler перед первой загрузкой и проверьте, сколько памяти занимает.

Кроме того, вы можете кэшировать и повторно использовать растровые изображения самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...