简体   繁体   中英

android listview outofmemory - ImageBitmaps

I have a ListView and a GridView both causing me problems and OutOfMemory errors when scrolling, I read online about the issue and saw this question so I used Sunil's first solution and implemented it in my code. the images for the GridView and ListView are at "/res/drawable/image1.png" and so on, I passed to the CustomAdapter class this int array public static int[] mDrawableImg = {R.drawable.back, R.drawable.arrows, R.drawable.bomber, R.drawable.archers, R.drawable.knight}; and used this:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    final Holder holder = new Holder();
    final View rowView = inflater.inflate(R.layout.program_list2, null);
    holder.img = (ImageView) rowView.findViewById(R.id.imageView1);
      holder.img.setImageResource(imageId[position]);
  //  holder.img.setImageBitmap(convertBitmap(String.valueOf(imageId[position])));
            return rowView;
}

Now as you see I added a line of code to load the image from Bitmap with a function called convertBitmap but my GridView is empty, its scrollable meaning there are items but the images are not loaded.

convertBitmap Function:

public static Bitmap convertBitmap(String path) {
    Bitmap bitmap = null;
    BitmapFactory.Options bfOptions = new BitmapFactory.Options();
    bfOptions.inDither = false;
    bfOptions.inTempStorage = new byte[32 * 1024];
    File file = new File(path);
    FileInputStream fs = null;
    try {
        fs = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    try {
        if (fs != null) {
            bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fs != null) {
            try {
                fs.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        }
    }
    return bitmap;
}

What have I done wrong and will it solve my OutOfMemory errors? thanks.

The error you get is absolutely logical. Look at this line in your getView() method:

final View rowView = inflater.inflate(R.layout.program_list2, null);

What does it mean? It means that you're creating a new instance of the item each time Android requests you a View for it. That's pretty insane, because you just create and create more views while you scroll the ListView (so is pretty natural that you get an out of memory error. And I'm sure your ListView is scrolling laggy).

And I bet Android Studio is warning you this issue by remarking that line in yellow color.

Affortunately, you can fix it very easily. But let me say you some things. Look at the View that you're receiving in the getView() method as a parameter. Don't you see it? Is the variable that you called convertView . And note that you're not using it. What is this View ? Is called a recycled view (Not to be confused with RecyclerView class). Is a view that was previously inflated and no longer used because is not visible for the user. And this, my friend, this is the key of your problem and also of your solution: Instead of inflate one new view each time, just recycle it. I promise you is very simple. Now your getView methos should look like this:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null)
        convertView = inflater.inflate(R.layout.program_list2, null);

    //final Holder holder = new Holder();
    //holder.img = (ImageView) convertView.findViewById(R.id.imageView1);
    //holder.img.setImageResource(imageId[position]);


    ImageView img = (ImageView) convertView.findViewById(R.id.imageView1);
    //Note you don't need the Holder
    Bitmap imageBitmap = convertBitmap(imageId[position]);
    if (imageBitmap != null)
        img.setImageBitmap(imageBitmap);
    else
        img.setImageBitmap(null);

    return convertView;
}

And please look at your usage of the ViewHolder pattern. You're using it wrong...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM