android - drawable.setCallback(null) 的后果;

标签 android callback null drawable

在尝试实现 Drawable 的小型内存缓存时,我了解到要避免在关闭 Activity 后发生内存泄漏,我需要取消绑定(bind)这些 Drawable:将它们的回调设置为 null。

因为维护缓存在每个 Activity 中的 Drawable 需要额外的代码,所以我尝试在 setImageDrawable(drawable) 之后立即解除它们的绑定(bind),到目前为止我没有看到任何后果.
这是来自 MyImageView 类的代码(extends ImageView):

setImageDrawable(drawable);
d.setCallback(null);

在调试器中,我可以清楚地看到,在第一行回调之前为 null,在第一行之后它被设置为这个 imageView,之后我再次将它设置为 null。它通常在那之后显示..

setCallback (Drawable.Callback cb) 的文档说明:

Bind a Drawable.Callback object to this Drawable. Required for clients that want to support animated drawables.

因为我不需要动画可绘制对象,所以我不明白为什么我不应该这样做,但令我困扰的是,在一些关于 Android 中关于可绘制对象的内存泄漏的博客中,只有在 Activity 完成后才这样做。问题是,为什么在绑定(bind)到 ImageView 时总是自动设置回调?

是否存在一些边界条件,回调设置为 null 的那些可绘制对象会导致问题?不显示或 NPE?

最佳答案

您不应该缓存 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 检索的任何 Drawables 实现自己的缓存。

而且,如果您在资源之外创建自己的 Drawable,我强烈建议对底层数据(例如从网络下载的位图)进行缓存,然后尝试破坏常量状态。 (同样,绝对不要自己缓存 Drawable 对象。)

关于android - drawable.setCallback(null) 的后果;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7648740/

相关文章:

Char* 在不应该的时候显示 null

android - 如何从可以输入 Spring Security 安全 Web 服务方法的 Android 应用发出请求?

android - 如何在android中的textview中设置运行时背景图像?

javascript - 多个 $.each 中的 setTimeout() 回调

c - UI 编程中除了回调还有其他选择吗?

javascript - Node.js 回调设计 - 如何在回调中使用 res

android - ScrollView如何设置多个 View ?

java - 三星 Galaxy Tab 7.0 在从相机 Intent 返回时重启应用程序

c# - IDisposable 字段怎么能在这里为空?

c# - 了解 C# 泛型和 Nullable 值类型。返回 null 或 nullable