我的应用程序包含多达40个5tabs的活动。每个活动都有一个背景图片。当我进入一项活动时,已加载并显示该活动的背景图像。当我离开该活动时,我正在onDestroy
方法中回收该图像。
上述过程工作正常,即加载位图和回收位图。
用于加载图片我正在使用以下步骤。
我使用缓存目录作为图像路径,使用哈希映射作为关键字,将图像路径作为关键字。
1)在最初加载图片的同时,我正在检查带有该图像路径的哈希图,如果它在那里,那么我只是将该位图设置为图像。
2)如果哈希映射不包含位图或位图已经回收,那么我正在检查缓存的路径可用性。
3)如果缓存包含,那么我正在使用这些url哈希码创建位图。
回收利用:
我的问题是
1)当我在几秒钟内启动应用程序时,堆大小增加到25到30 mb,这会在几分钟内导致OutOfMemeory
。
2)当我开始活动时,即使我正在维护缓存和哈希映射,堆大小也会增加以加载映像。
有没有办法最小化堆内存和任何其他存储位图的方法。
任何人都可以帮助我如何面对这种情况
我在下面发布一些代码。
提前致谢 Venkat。
我的代码是:
public ConcurrentHashMap<String, WeakReference<Bitmap>> cache=new ConcurrentHashMap<String, WeakReference<Bitmap>>();
public void DisplayImage(String url,Activity activity, View imageView,int width,int height)
{
this.REQUIRED_WIDTH = width;
this.REQUIRED_HEIGHT = height;
if(cache.containsKey(url) && cache.get(url).get() != null && !cache.get(url).get().isRecycled())
{
if(imageView instanceof ImageView)
{
((ImageView)imageView).setImageBitmap(cache.get(url).get());
}
else
imageView.setBackgroundDrawable(new BitmapDrawable(cache.get(url).get()));
}
else
{
if(cache.containsKey(url))
{
cache.remove(url);
}
queuePhoto(url, activity, imageView);
if(imageView instanceof ImageView)
{
((ImageView)imageView).setBackgroundResource(stub_id);
}
else
{
imageView.setBackgroundColor(Color.parseColor(AppConstants.customCollection.HomeScreen));
}
}
}
public void recycleBitmaps(final String backgroundImageUrl)
{
new Handler().postDelayed(new Runnable()
{
public void run()
{
stopThread();
Vector<WeakReference<Bitmap>> vecBitmapRef = new Vector<WeakReference<Bitmap>>();
if(!cache.isEmpty())
{
if(backgroundImageUrl!=null && !backgroundImageUrl.equalsIgnoreCase(""))
{
WeakReference<Bitmap> bmpref = (WeakReference<Bitmap>)cache.get(backgroundImageUrl);
if(bmpref!=null && bmpref.get()!=null && !bmpref.get().isRecycled())
{
vecBitmapRef.add(cache.remove(backgroundImageUrl));
}
}
Set<String> keys = cache.keySet();
for(String key: keys)
{
vecBitmapRef.add(cache.remove(key));
}
Log.e("Bitmap size", ""+vecBitmapRef.size());
try
{
for(WeakReference<Bitmap> bitmapRef : vecBitmapRef)
{
if(bitmapRef != null && bitmapRef.get() != null)
{
if(!bitmapRef.get().isRecycled())
{
bitmapRef.get().recycle();
bitmapRef.enqueue();
bitmapRef =null;
}
}
Runtime.getRuntime().gc();
}
}
catch (Exception e)
{
// TODO: handle exception
}
vecBitmapRef.clear();
cache.clear();
}
}
},500);
}
答案 0 :(得分:0)
我假设你有每个活动的imageView。我认为一些活动及其附加视图不会被破坏,因此ImageViews会维护对您的位图的引用,因此,bitmapRef.get()不会返回null,因为imageViews具有对其底层位图的强引用。
要确认此假设,您可以尝试堆转储以查看内存的累积。
Android ==> Memory Analysing ==> Eclipse memory analyzer?
希望它会有所帮助!