在尝试实现Drawables的小型内存缓存时,我了解到为了避免在关闭活动后出现内存泄漏,我需要取消绑定那些Drawable:将它们的回调设置为null。
由于维护每个活动中缓存的Drawables需要额外的代码,我试图在setImageDrawable(drawable)
后解除绑定 ,到目前为止我没有看到任何后果。
这是来自MyImageView类(extends ImageView
)的代码:
setImageDrawable(drawable);
d.setCallback(null);
在调试器中我可以清楚地看到,在第一行回调为空之前,在第一行之后它被设置为此imageView,之后我再次将其设置为null。它通常在那之后显示..
setCallback (Drawable.Callback cb)
州的文档:
将Drawable.Callback对象绑定到此Drawable。对于想要支持动画drawable的客户来说是必需的。
由于我不需要动画drawable,我不明白为什么我不应该这样做但是让我感到困扰的是,在几个博客中关于Android中关于drawables的内存泄漏这只是在活动完成后才完成的。问题是,为什么绑定到ImageView
时会自动设置回调?
是否存在某些边界条件,其中回调设置为null的drawable将导致问题?没有显示或NPE?
答案 0 :(得分:19)
你不应该缓存Drawables - Drawable对象是非常有状态的,并且只供一个所有者使用。
如果要实现缓存,则应该缓存drawable的常量状态。
使用以下方法检索常量状态:
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#getConstantState()
(注意此方法可以返回null;并非所有Drawable都具有常量状态。)
您可以稍后使用以下方法从常量状态实例化新的Drawable:
另请注意,Resources已经使用此工具为您维护了Drawables的缓存,因此您无需为从Resources中检索的任何Drawable实现自己的缓存。
如果您在资源之外创建自己的Drawable,我强烈建议您创建基础数据的缓存(例如从网络下载的位图),然后尝试混淆常量状态。 (再次,绝对不要自己缓存Drawable对象。)