处理位图时发生内存泄漏
问题描述:
我试图释放内存,当我不再需要它时,但这似乎并不容易。我创建了一个包含一些图像(位图)的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。如果我不再需要它,我怎样才能释放记忆?完成()没有帮助。
答
首先,在需要之前不要加载图像。假设您在该目录中有100个图像。最有可能的是,用户无法看到他们将不得不滚动屏幕—的所有100。如果用户不滚动,则无意中加载了看不见的图像。
其次,不要加载已加载的图像。如果您“多次打开包含该列表的活动”,并且您每次都加载所有图像,那么这很浪费,因为您之前加载了许多这些图像。
总体而言,不自己加载图像。有很多可用的image-loading libraries,如毕加索和Glide。一个体面的图像加载库将有一个可配置的缓存(解决我的第二点),并知道如何在后台加载图像,即使从ListView
或RecyclerView
(解决我的第一点)的行。
完成后,您可以回收位图。 – Thracian
使用'Glide'库或'Picasso'下载图像。这些库是为处理图像而制作的。 – Yupi
我用我的代码处理图像,从来没有与他们的问题。你可以使用你自己的代码来处理图像,但是如果它们太大,你应该在加载它们之前调整它们的大小,特别是如果它们大于将要放入的容器或布局,请不要一次将它们加载到内存中,完成后回收它们。我用这种方式开发游戏。 – Thracian