2014-02-21 64 views
1

如果你認爲我正在開發的應用像Facebook一樣(至少這會給你一個我正在做的事情的背景),那麼理解它會容易一些。我有一個使用navigationdrawer在片段之間交換的活動,每個片段都可以有一個到幾個「subFragments」---將這些片段視爲單獨的帖子,像textview,幾個按鈕和一個ImageView。創建「容器片段」時,我會調用服務器並獲取所需的數據以創建所有「子片段」。然後我遍歷數據並將所有「子片段」添加到「容器片段」的視圖中。由於圖像緩存導致的Android OOM錯誤?

我注意到我似乎正在使用過高的內存量(大約129 MB)。

當創建子片段時,我會調用這個異步任務,它將每個片段從服務器獲取的圖像拖放到ImageView中。

public class URLImageFactory extends AsyncTask<String, Void, Bitmap> 
{ 
    ImageView imgView; 
    private static final ImgCache mCache = new ImgCache(); 

    public URLImageFactory(ImageView bmImage) { 
     this.imgView = bmImage; 
    } 

    @Override 
    protected Bitmap doInBackground(String... urls) { 
     String urldisplay = Config.SERVER_URL + urls[0].replaceAll("\\s+","%20"); 

     Bitmap bitmap = null; 
     //If it is in the cache don't bother pulling it from the server 
     if(bitmap != null) 
     { 
      return bitmap; 
     } 

     try { 
      InputStream in = new java.net.URL(urldisplay).openStream(); 
      //This is in case we are using match_parent/wrap content 
      if(imgView.getWidth() == 0 || imgView.getHeight() == 0) 
      { 
       bitmap = BitmapFactory.decodeStream(in); 
      } else { 
       bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(in), 
         imgView.getWidth(), imgView.getHeight(), false); 
      } 
      mCache.put(urldisplay,bitmap); 
     } catch (Exception e) { 
      Log.e("Error", e.getMessage()); 
      e.printStackTrace(); 
     } 
     return bitmap; 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     imgView.setImageBitmap(result); 
    } 
} 

我在緩存圖像來加快這一進程

公共類ImgCache做了初步嘗試擴展LruCache {

public ImgCache() { 
     super(calculateCacheSize()); 
    } 

    public static int calculateCacheSize() 
    { 
     int maxMemory = (int) Runtime.getRuntime().maxMemory()/8; 
     int cacheSize = maxMemory; 
     return cacheSize; 
    } 

    @Override 
    protected int sizeOf(String key, Bitmap value) { 
     return value.getByteCount()/1024; 
    } 
} 

我的應用程序與內存不足的異常崩潰。我也注意到,當我的「容器片段」被換出一個不同的...通常是一個類似結構的片段...這些子片段的onPause()和onStop()沒有被解僱。如果它幫助子片段是靜態內部類而容器片段不是。我認爲這是一個與位圖相關的問題,但我不確定。我試圖在所有子片段上使用TransactionManager.remove(片段),當父命中onPause但它似乎沒有幫助。

+0

您是否嘗試過使用eclipse內存分析器來查看哪些對象在應用程序中佔用內存?另外,要指出'Runtime.getRuntime()。maxMemory()'告訴你的字節數。你爲什麼把它除以8? –

+0

我把它除以8,因爲我認爲內存的1/8適合緩存......更多的是猜測 – ed209

+0

我不禁注意到,每次它將位圖添加到UI中時,它都會吐出增長堆(frag case)#### – ed209

回答

2

您將每個對象的字節數除以1024,但只將可用內存除以8;結果是LRU緩存可能會填充128倍的可用內存。從sizeOf中刪除/ 1024,你應該很好。

相關問題