2013-03-01 103 views
0

我的应用程序包含如此多的活动,最多40个5tabs。每个活动都有一个背景图片。当我进入一个活动时,该活动的背景图像已被加载并显示。当我离开该活动时,我正在回收onDestroy方法中的该图像。当应用程序启动时堆大小增加到35mb

上述过程正在完美运行,即加载位图并回收位图

用于加载图像我正在使用以下步骤。

我使用图像路径的缓存目录和图像路径作为关键字的位图散列图。

  • 1),而装载图像最初我检查散列映射与该图像路径,如果它是存在的话,我简单地设置该位图图像。 2)如果哈希映射不包含位图或位图已经回收,那么我正在检查缓存的路径可用性。 3)如果缓存包含然后我创建与这些网址哈希代码的位图。

对于回收:

  • 1)我在哈希映射与该图像路径检查和回收该位图。

我的问题是

  • 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

我假设你有每个活动的ImageView的。我认为一些活动及其附加视图不会被销毁,因此ImageView会保留对位图的引用,因此,由于imageViews对其下层位图有强烈的参考,因此bitmapRef.get()不会返回null。

要确认这个假设,您可以尝试堆转储来查看内存的积累。

Android ==> Memory Analysing ==> Eclipse memory analyzer?

希望它能帮上忙!