Последствия 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.)