2012-01-31 51 views
1

我在我的android应用程序中有一个网格视图。我从服务器加载图像到网格视图。我使用延迟加载。我必须回收在此处创建的所有位图。如何在Adapter或Grid视图中执行Bitmap.recycle()。我越来越内存,请帮助我。如何回收GridView适配器中的位图?

回答

6

您将需要显示一些代码(至少是您的适配器)。如果你的内存出错,你可能没有正确地实现视图回收,或者有其他内存泄漏。也有可能你只是一次加载太多的大型位图,但是如果你可以加载视图,那么它更有可能发生内存泄漏。

没有人能够在不查看某些代码的情况下追踪内存泄漏。 Bitmap.recycle()不是解决方案,如果代码的其余部分没有问题,垃圾收集器将无法正常工作。

请参阅:http://www.youtube.com/watch?v=_CruQY55HOk关于管理android中的内存以及发现内存泄漏的热门话题。

另请尝试:http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html了解如何下载或以其他方式正确异步加载图像到视图列表中的示例。

编辑:还检查了图像加载库我写的,所以你不必担心任何这样的:https://github.com/bumptech/glide

2

有工作得非常好一个非常简单的方法:

首先,你必须创建一个自定义的ImageView这样的:

public class ImageViewRecyclable extends ImageView 
{ 
    private Bitmap bitmap; 

    public ImageViewRecyclable(Context context) 
    { 
     super(context); 
    } 

    @Override 
    public void setImageBitmap(Bitmap bm) 
    { 
     super.setImageBitmap(bm); 
     if (bitmap != null) bitmap.recycle(); 
     this.bitmap = bm; 
    } 
} 

我们ImageViewRecyclable保持一个指向位图和回收旧在设置新的之前。

其次,您必须检查适配器的getView以查看convertView是否为null。如果它不是null投射到我们的自定义ImageViewRecyclable并在其上设置位图。这种方法在设置新的位图之前会回收旧的位图。

这是适配器的getView代码:

@Override 
public View getView(int position, View convertView, ViewGroup parent) 
{ 
    ImageViewRecyclable imageView = (convertView == null) ? new ImageViewRecyclable(ActivityMain.this) : (ImageViewRecyclable) convertView; 
    byte[] bytes = .... 
    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
    imageView.setImageBitmap(bitmap); 

    return imageView; 
} 

我测试此代码与1000个100x100的图像。在显示50张带有内存错误的图像后,原始ImageView失败,但此代码运行良好,直到网格结束。

此代码适用于小型离线图像,但在线和大型图像需要缓存和其他内容。这可能很有用,但必须应用一些更改。

相关问题