2017-10-18 54 views
0

我試圖釋放內存,當我不再需要它時,但這似乎並不容易。我創建了一個包含一些圖像(位圖)的ListView。每次我這樣做,內存監視器顯示我的應用程序使用的內存增加。這就是我的做法:處理位圖時發生內存泄漏

private ArrayList<ImgMdl> populateList(){ 

    ArrayList<ImgMdl> list = new ArrayList<>(); 

    File folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + settingsFileDir + "/" + imgLogFileDir); 

    if(folder.exists()) { 
     File[] listOfFiles = folder.listFiles(); 
     listOfFiles = sortFileList(listOfFiles); 

     for (int i = 0; i < listOfFiles.length; i++) { 
      String imgFilePath = listOfFiles[i].toString(); 
      Bitmap bmp = BitmapFactory.decodeFile(imgFilePath); 
      ImgMdl imgMdl = new ImgMdl(); 
      imgMdl.set_itm_txt(getDateString(listOfFiles[i].getName())); 
      imgMdl.set_itm_img(bmp); 
      list.add(imgMdl); 
     } 
    } 

    return list; 
} 



public class MainGate_ImgMdl { 

private String itm_txt; 
private Bitmap itm_img; 

public String get_itm_txt() { 
    return itm_txt; 
} 

public void set_itm_txt(String itm_txt) { 
    this.itm_txt = itm_txt; 
} 

public Bitmap get_itm_img() { 
    return itm_img; 
} 

public void set_itm_img(Bitmap itm_img) { 
    this.itm_img = itm_img; 
} 

} 

如果我多次打開包含該列表的活動,我會有時會發生outOfMemoryException。如果我不再需要它,我怎樣才能釋放記憶?完成()沒有幫助。

+1

完成後,您可以回收位圖。 – Thracian

+0

使用'Glide'庫或'Picasso'下載圖像。這些庫是爲處理圖像而製作的。 – Yupi

+0

我用我的代碼處理圖像,從來沒有與他們的問題。你可以使用你自己的代碼來處理圖像,但是如果它們太大,你應該在加載它們之前調整它們的大小,特別是如果它們大於將要放入的容器或佈局,請不要一次將它們加載到內存中,完成後回收它們。我用這種方式開發遊戲。 – Thracian

回答

2

首先,在需要之前不要加載圖像。假設您在該目錄中有100個圖像。最有可能的是,用戶無法看到他們將不得不滾動屏幕—的所有100。如果用戶不滾動,則無意中加載了看不見的圖像。

其次,不要加載已加載的圖像。如果您「多次打開包含該列表的活動」,並且您每次都加載所有圖像,那麼這很浪費,因爲您之前加載了許多這些圖像。

總體而言,不自己加載圖像。有很多可用的image-loading libraries,如畢加索和Glide。一個體面的圖像加載庫將有一個可配置的緩存(解決我的第二點),並知道如何在後臺加載圖像,即使從ListViewRecyclerView(解決我的第一點)的行。