简体   繁体   English

使用ListView和Bitmap时Android内存不足错误

[英]Android out of memory error when using ListView and Bitmap

I have used ViewHolder + Bitmap decodes/compress and imageCache in my ListView so i can no longer have out of memory error but unfortunately i'm still getting it, it happens mostly when i'm back to my ListView Activity from another Activity, or when i go from my current ListView Activity to another ListView Activity. 我在ListView中使用了ViewHolder + Bitmap解码/压缩和imageCache,所以我再也不会出现内存不足的错误,但是不幸的是我仍然得到它,这种情况主要发生在我从另一个Activity返回到ListView Activity时,或者当我从当前的ListView活动转到另一个ListView活动时。 Can anyone please tell me if i'm missing something? 有人可以告诉我我是否想念东西吗? here's my code: 这是我的代码:

private class MyAdapter extends ArrayAdapter<String> {

     LruCache<Integer, Bitmap> imageCache;

        public MyAdapter(Context context, int resource, int textViewResourceId, String[] strings) {
            super(context, resource, textViewResourceId, strings);

            final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
            final int casheSize = maxMemory / 8;
            imageCache = new LruCache<>(casheSize);
         }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolderItem viewHolder;
            String[] names = getResources().getStringArray(R.array.grilled_fresh_beef_names);
            String[] prices = getResources().getStringArray(R.array.grilled_fresh_beef_prices);
            String[] ingredients = getResources().getStringArray(R.array.grilled_fresh_beef_ingredients);

            if(convertView==null) {
                LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.categories_item, parent, false);


                viewHolder = new ViewHolderItem();

                viewHolder.item_name = (TextView) convertView.findViewById(R.id.items_name);
                viewHolder.item_price = (TextView) convertView.findViewById(R.id.item_price);
                viewHolder.item_ingredient = (TextView) convertView.findViewById(R.id.ingredients);
                viewHolder.imageView = (ImageView) convertView.findViewById(R.id.item_image);
                viewHolder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

                convertView.setTag(viewHolder);

            } else {
                viewHolder = (ViewHolderItem) convertView.getTag();
            }


         viewHolder.item_name.setText(names[position]);
            viewHolder.item_price.setText(prices[position]);
            viewHolder.item_ingredient.setText(ingredients[position]);



            Bitmap bitmap = imageCache.get(position);
            if (bitmap == null) {
                bitmap = BitmapFactory.decodeResource(getResources(), beef_burger[position]);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);


                imageCache.put(position, bitmap);
            }

            viewHolder.imageView.setImageBitmap(bitmap);

            return convertView;
        }


     }

logcat的

The problem using the lru cache the way you do is you are keep a reference to all the bitmaps you create even the one ones that are not on screen. 使用lru缓存的问题是,您要保留对创建的所有位图的引用,即使是那些不在屏幕上的位图。 Android is not able to garbage collect these and resuse them because of this reference to the lru cache. 由于无法引用lru缓存,因此Android无法对其进行垃圾回收并重新使用。

As the other answer stated its better to use a library to take care of the caching for you. 正如另一个答案所言,最好使用库来为您处理缓存。 I would recommend Picasso or Glide . 我会推荐PicassoGlide

I personally use glide. 我个人使用滑行。 It seems to load images that bit faster and its perfect for loading images in a listview. 似乎加载图像的速度更快,并且非常适合在列表视图中加载图像。

Its as simple as 它就像

Glide.with(context)
    .load(***image file/path/bitmap***)
    .into(viewHolder.imageView);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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