可绘制的位图与单个可重用位图的内存更好?
据我了解(并非我是正确的)当应用程序完成使用可绘制对象时,它们通常会正确地从内存中删除。然而,位图需要手动回收,有时甚至需要编写一个特殊的类来正确处理它们。 我的问题是,关于内存和泄漏,简单地坚持使用 Drawables 是否更有益:像这样:
myView.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image));
myView1.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image1));
myView2.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image2));
而不是像这样使用位图:
Bitmap tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
myView.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image1);
myView1.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image2);
myView2.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
我当然也读过,你必须小心位图上的 recycle() 方法,因为它们可以在仍在使用时被删除?这些问题似乎不断以不同的形式出现,但我无法从任何人那里得到关于此事的直接答案。有人说要重用位图并在每次使用后回收,而其他人则说使用 Drawables 和 unbindDrawables() 方法(这就是我一直在使用的方法):
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
不过,任何适用的见解将不胜感激。谢谢
As I understand it (not that I'm correct) Drawables are generally correctly removed from memory when the application is finished with them. Bitmaps however need to be manually recycled, and sometimes even have a special class written to handle them properly. My question is, in regards to memory and leaks, is it more beneficial to simply stick with Drawables like such:
myView.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image));
myView1.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image1));
myView2.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image2));
rather than something like so with Bitmaps:
Bitmap tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
myView.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image1);
myView1.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image2);
myView2.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
I've also read of course that you have to be careful about recycle() method on Bitmaps because they can be removed while still in use? It seems like these issues keep popping up in different forms, but I can't really get a straight answer from anyone on the matter. One person says to reuse a Bitmap and recycle after every use, and others say use Drawables and an unbindDrawables() method (this is what I've been using):
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
Any applicable insight would be much appreciated though. Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
位图不需要手动回收。它们像 Drawables 和其他对象一样被垃圾收集。同样,您不需要取消绑定可绘制对象,除非在非常特殊的情况下。看来你读了很多误导性的信息。
回收位图和取消绑定可绘制对象在某些情况下可能很有用(例如,如果您的应用程序操作大量位图数据或以静态方式存储可绘制对象。)
您在问题开头显示的两个示例是等效的。如果您直接加载可绘制对象,则将代表您加载位图。如果您手动加载位图并将其设置在 ImageView 上,它们将代表您封装在可绘制对象中。
使用第一个解决方案,因为它更简单,并且在您真正需要它们之前不必担心解除绑定和其他内存管理技术。
Bitmaps do not need to be manually recycled. They are garbage collected just like Drawables and other objects. Similarly you don't need to unbind drawables, except in very specific situations. It seems that you read a lot of misleading information.
Recycling bitmaps and unbinding drawable can be useful in some situations (for instance if your app manipulate large amounts of bitmap data or if you store drawable in a static manner.)
The two examples you show at the beginning of your question are equivalent. If you load a drawable directly, bitmaps will be loaded on your behalf. If you load bitmaps manually and set them on an ImageView, they will be enclosed in drawables on your behalf.
Use the first solution since it's simpler and don't worry about unbinding and other memory management techniques until you actually need them.
我支持罗曼的提议,但我不确定你的问题是否能解决你的实际问题。我不知道你如何处理对视图的引用。也许您的应用程序中只是存在内存泄漏? Android中很多内存泄漏都与
Context
有关。当Drawable
附加到View
时,View
被设置为Drawable
上的回调。在上面的代码片段中,这意味着
Drawable
具有对TextView
的引用,而后者本身又具有对Activity
的引用(Context
),它又引用了几乎所有内容,具体取决于您的代码。在不查看更多代码的情况下,我猜您在销毁
Activity
时将存储的可绘制对象的回调设置为null
是正确的。I back Romain's proposal, but I'm not sure your question is addressing your actual problem. I don't know how you handle the references to your Views. Maybe you simply have memory leaks in your application? A lot of memory leaks in Android are related to
Context
. When aDrawable
is attached to aView
, theView
is set as a callback on theDrawable
.In the code snippet above, this means the
Drawable
has a reference to theTextView
which itself has a reference to theActivity
(theContext
) which in turns has references to pretty much anything depending on your code.Without looking at more of your code I guess you're on the right track by setting the stored drawables' callbacks to
null
when anActivity
is destroyed.