Ошибка удаления растровых изображений [Android] - PullRequest
0 голосов
/ 23 ноября 2010

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

Если я нарисую около 50 растровых изображений на экране, оно будет принудительно закрываться при первой очистке, но если я только рисую 5Я могу получить около 10 Клиров, прежде чем он рухнет.Я предполагаю, что это как-то связано с тем, что GC неправильно очищает растровые изображения.У кого-нибудь есть идеи на эту тему?

Ответы [ 2 ]

1 голос
/ 23 ноября 2010

ОК - теперь трассировка стека присоединена: ConcurrentModificationException Вы модифицируете ArrayList из разных потоков или перебираете его.Либо вам нужно синхронизировать доступ, либо использовать другую коллекцию, например ConcurrentHashSet.

Но, возможно, будет интересно и следующее (мой исходный ответ): p

Похоже, что вы кешируете реальноеРастровые объекты с данными всего пикселя -> Полагаю, вы получили OutOfMemoryException

Сборщик мусора является асинхронной операцией, и если вы очищаете свой растровый массив, растровые изображения не выгружаются из памяти мгновенно.Если вы вставляете новые, может случиться так, что старые все еще находятся в памяти, а новые тоже загружаются.

Решение: не кэшируйте растровые изображения таким образом, вы делаете.

Это разные вещи, которые вы можете попробовать (зависит от вашего конкретного сценария):

1) Если они хранятся на SD-карте или чем-то еще, кэшируйте только путь к растровым изображениям в вашей коллекции и загружайтеих, если они необходимы для рисования.

2) Используйте Drawable объекты вместо растровых изображений - у них есть несколько интересных методов и алгоритмов для оптимизированного доступа к растровым данным.

3) Для оптимизациипроизводительность использовать что-то вроде SoftReference или подобное - может быть WeakRefernce .SoftReferences могут быть выгружены GC по требованию (когда памяти становится мало).В этом случае вы должны проверить, является ли мягкое отражение нулевым или все еще существует.Например:

ArrayList<SoftReference<Bitmap>> _graphics = new ArrayList<SoftReference<Bitmap>>();
...

for (int i = 0; i < _graphics.size(); i++)
{
    Bitmap b = _graphics.get(i).get();
    if (b == null)
    {
        b = loadFromSomewhere(i);
        _graphics.add(new SoftReference<Bitmap>(b), i);
    }
    ... do something wwith your bitmap
}

Этот фрагмент кода не тестировался и не записывался с помощью редактора Java (извините за ошибки при вводе или неправильные сигнатуры методов).

1 голос
/ 23 ноября 2010

Переход по файлу Logcat Я, кажется, обнаружил ошибку (Новый Android Dev: p даже не знал, что она существует)Это произошло из-за исключения ConcurrentModificationException.Кажется, все работает сейчас = D

...