drawable.setCallback(null); 的后果

发布于 2024-12-08 05:21:41 字数 797 浏览 0 评论 0原文

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

由于维护在每个 Activity 中缓存的 Drawable 需要额外的代码,因此我尝试在 setImageDrawable(drawable) 之后立即取消绑定它们,但到目前为止我还没有看到任何后果。
这是来自 MyImageView 类(extends ImageView)的代码:

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

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

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

将一个 Drawable.Callback 对象绑定到该 Drawable。对于想要支持动画绘图的客户端来说是必需的。

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

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

While trying to implement small in-memory cache of Drawables, I learned that to avoid memory leaks after closing activity I need to unbind those Drawables: set their callback to null.

Because maintaining Drawables cached in each activity would require extra code, I tried to unbind them immediately after setImageDrawable(drawable) and I don't see any consequences so far.
This is code from MyImageView class (extends ImageView):

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

In debugger I can clearly see that before first line callback is null, after first line it is set to this imageView, and after that I set it to null again. It is normally shown after that..

Documentation for setCallback (Drawable.Callback cb) states:

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

Since I don't need animated drawable, I don't see why I shouldn't do this but it bothers me that in several blogs about memory leakage in Android concerning drawables this is done only after activity is done. Question is, why is callback always automatically set when binding to ImageView?

Are there some border conditions where those drawables with callback set to null will cause a problem? Not displaying or NPE?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

做个少女永远怀春 2024-12-15 05:21:41

您不应该缓存 Drawables——Drawable 对象是有状态的,并且只能由一个所有者使用。

如果你想实现缓存,你应该缓存可绘制对象的常量状态。

通过以下方式检索常量状态:

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

(请注意,此方法可以返回 null;并非所有 Drawable 都具有恒定状态。)

您可以稍后实例化 new从恒定状态绘制:

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

另请记住,资源使用此工具已经为您维护了一个 Drawable 缓存,因此您无需为从资源中检索的任何 Drawable 实现自己的缓存。

如果您要在资源之外制作自己的 Drawable,我强烈建议您对底层数据(例如从网络下载的位图)进行缓存,然后尝试扰乱恒定状态。 (再次强调,绝对不要缓存 Drawable 对象本身。)

You should not cache Drawables -- the Drawable object is very stateful, and intended to be used by one and only one owner.

If you want to implement a cache, you should be caching the drawable's constant state.

The constant state is retrieve with this:

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

(Note this method can return null; not all Drawables have constant state.)

You can later instantiate new Drawables from a constant state with this:

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

Also keep in mind that Resources already maintains a cache of Drawables for you, using this facility, so there is no need for you to implement your own cache for any Drawables you are retrieving from Resources.

And if you are making your own Drawables outside of resources, I would strongly recommend making a cache of the underlying data (such as a bitmap downloaded from the network) then trying to mess with the constant state. (And again, definitely don't cache Drawable objects themselves.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文