Последствия drawable.setCallback(null);
При попытке реализовать небольшой кеш-память в Drawables, я узнал, что, чтобы избежать утечек памяти после закрытия активности, мне нужно отпереть эти Drawables: установите для их обратного вызова значение null.
Поскольку для хранения Drawables, кэшированных в каждом действии, потребуется дополнительный код, я попытался отвязать их сразу после setImageDrawable(drawable)
, и я пока не вижу никаких последствий.
Это код из класса MyImageView (extends ImageView
):
setImageDrawable(drawable);
d.setCallback(null);
В отладчике я могу ясно видеть, что перед первым обратным вызовом первой строки, после первой строки он установлен на этот образView, а после этого я снова установил его в null. Обычно это отображается после этого.
Документация для setCallback (Drawable.Callback cb)
гласит:
Привязать объект Drawable.Callback к этому Drawable. Требуется для клиентов, которые хотят поддерживать анимированные чертежи.
Так как мне не нужен анимированный drawable, я не понимаю, почему я не должен этого делать, но меня беспокоит, что в нескольких блогах об утечке памяти в Android в отношении чертежей это делается только после того, как активность завершена. Вопрос в том, почему callback всегда автоматически устанавливается при привязке к ImageView
?
Есть ли какие-то граничные условия, когда эти чертежи с обратным вызовом равны нулю, вызовут проблему? Не отображается или NPE?
Ответы
Ответ 1
Вы не должны кэшировать Drawables - объект Drawable очень сдержан и предназначен для использования одним и только одним владельцем.
Если вы хотите реализовать кеш, вы должны кэшировать возвращаемое константное состояние.
Постоянное состояние извлекается с помощью этого:
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#getConstantState()
(Обратите внимание, что этот метод может возвращать null; не все Drawables имеют постоянное состояние.)
Вы можете позже создавать новые Drawables из постоянного состояния с помощью этого:
http://developer.android.com/reference/android/graphics/drawable/Drawable.ConstantState.html#newDrawable (android.content.res. Ресурсы)
Также имейте в виду, что у Ресурсов уже есть кэш Drawables для вас, используя этот механизм, поэтому вам не нужно реализовывать свой собственный кеш для любых Drawables, которые вы извлекаете из ресурсов.
И если вы создаете свои собственные Drawables за пределами ресурсов, я настоятельно рекомендую сделать кэш базовых данных (например, растровое изображение, загруженное из сети), а затем попытаться связать себя с постоянным состоянием. (И опять же, определенно не кэшировать сами объекты Drawable.)