user3137385
user3137385

Reputation: 315

memory leak while handling bitmaps

I'm trying to free memory when I don't need it any more but that doesn't seem to be easy. I create a ListView containing some images (Bitmaps). Every time I do that, the memory monitor shows increase of memory used by my app. This is how I do it:

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;
}

}

If I open the activity containing that list several times, I'll sometime get an outOfMemoryException. How can I free memory if I don't need it any more? finish() doesn't help.

Upvotes: 0

Views: 48

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006769

First, do not load images until they are needed. Suppose that you have 100 images in that directory. Most likely, the user cannot see all 100 on the screen — they would have to scroll to do that. If the user does not scroll, you have loaded the unseen images for no reason.

Second, do not load images that you already loaded. If you "open the activity containing that list several times", and you are loading all of the images each time, that is a waste, as you loaded many of those images previously.

Overall, do not load images yourself. There are plenty of image-loading libraries that are available, such as Picasso and Glide. A decent image-loading library will have a configurable cache (addressing my second point) and know how to load images on-demand in the background, even from rows in a ListView or RecyclerView (addressing my first point).

Upvotes: 2

Related Questions