可绘制与单个可重用位图在内存上更好? [英] Drawable vs Single reusable Bitmap better with memory?

查看:18
本文介绍了可绘制与单个可重用位图在内存上更好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知(并不是说我是对的)Drawables 通常会在应用程序完成后从内存中正确删除.然而位图需要手动回收,有时甚至需要编写一个特殊的类来正确处理它们.我的问题是,关于内存和泄漏,像这样简单地坚持使用 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() 方法,因为它们可以在仍在使用时被删除?这些问题似乎不断以不同的形式出现,但我真的无法从任何人那里得到直接的答案.有人说每次使用后都要重用 Bitmap 并回收,其他人说使用 Drawables 和 unbindDrawables() 方法(这是我一直在使用的):

private void unbindDrawables(View view) {如果 (view.getBackground() != null) {view.getBackground().setCallback(null);}如果(查看 ViewGroup 的实例){for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {unbindDrawables(((ViewGroup) view).getChildAt(i));}((ViewGroup) 视图).removeAllViews();}}

不过,任何适用的见解将不胜感激.谢谢

解决方案

我支持 Romain 的提议,但我不确定您的问题是否解决了您的实际问题.我不知道您如何处理对您的视图的引用.也许您的应用程序中只是存在内存泄漏?Android中的很多内存泄漏都与Context有关.当 Drawable 附加到 View 时,View 被设置为 Drawable 的回调.>

TextView myView = new TextView(this);myView.setBackgroundDrawable(getDrawable(R.drawable.my_bitmap));

在上面的代码片段中,这意味着 Drawable 引用了 TextView,后者本身引用了 Activity(Context) 反过来又引用了几乎所有取决于您的代码的内容.

在不查看更多代码的情况下,我猜当 Activity 被销毁时,通过将存储的可绘制对象的回调设置为 null,您是在正确的轨道上.>

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

解决方案

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 a Drawable is attached to a View, the View is set as a callback on the Drawable.

TextView myView = new TextView(this);
myView.setBackgroundDrawable(getDrawable(R.drawable.my_bitmap));

In the code snippet above, this means the Drawable has a reference to the TextView which itself has a reference to the Activity (the Context) 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 an Activity is destroyed.

这篇关于可绘制与单个可重用位图在内存上更好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆