2013-03-01 97 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?

希望它能幫上忙!