处理位图时发生内存泄漏

问题描述:

我试图释放内存,当我不再需要它时,但这似乎并不容易。我创建了一个包含一些图像(位图)的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

首先,在需要之前不要加载图像。假设您在该目录中有100个图像。最有可能的是,用户无法看到他们将不得不滚动屏幕—的所有100。如果用户不滚动,则无意中加载了看不见的图像。

其次,不要加载已加载的图像。如果您“多次打开包含该列表的活动”,并且您每次都加载所有图像,那么这很浪费,因为您之前加载了许多这些图像。

总体而言,不自己加载图像。有很多可用的image-loading libraries,如毕加索和Glide。一个体面的图像加载库将有一个可配置的缓存(解决我的第二点),并知道如何在后台加载图像,即使从ListViewRecyclerView(解决我的第一点)的行。