drawable.setCallback(null)的后果;

时间:2011-10-04 13:34:32

标签: android callback null drawable

在尝试实现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?

1 个答案:

答案 0 :(得分:19)

你不应该缓存Drawables - Drawable对象是非常有状态的,并且只供一个所有者使用。

如果要实现缓存,则应该缓存drawable的常量状态。

使用以下方法检索常量状态:

http://developer.android.com/reference/android/graphics/drawable/Drawable.html#getConstantState()

(注意此方法可以返回null;并非所有Drawable都具有常量状态。)

您可以稍后使用以下方法从常量状态实例化新的Drawable:

http://developer.android.com/reference/android/graphics/drawable/Drawable.ConstantState.html#newDrawable(android.content.res.Resources)

另请注意,Resources已经使用此工具为您维护了Drawables的缓存,因此您无需为从Resources中检索的任何Drawable实现自己的缓存。

如果您在资源之外创建自己的Drawable,我强烈建议您创建基础数据的缓存(例如从网络下载的位图),然后尝试混淆常量状态。 (再次,绝对不要自己缓存Drawable对象。)