【问题标题】:Android out of memory error when using ListView and BitmapAndroid 使用 ListView 和 Bitmap 时出现内存不足错误
【发布时间】:2015-07-14 00:46:42
【问题描述】:

我在我的 ListView 中使用了 ViewHolder + Bitmap 解码/压缩和 imageCache,所以我不再有内存不足的错误,但不幸的是我仍然得到它,它主要发生在我从另一个返回我的 ListView Activity 时Activity,或者当我从当前的 ListView Activity 转到另一个 ListView Activity 时。 谁能告诉我我是否遗漏了什么?这是我的代码:

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


     }

【问题讨论】:

    标签: java android listview bitmap out-of-memory


    【解决方案1】:

    使用 lru 缓存的问题在于,您要保留对您创建的所有位图的引用,即使是那些不在屏幕上的位图。由于对 lru 缓存的引用,Android 无法垃圾收集并重新使用它们。

    正如另一个答案所说,最好使用库来为您处理缓存。我会推荐PicassoGlide

    我个人使用滑翔。它似乎加载图像的速度更快,并且非常适合在列表视图中加载图像。

    就这么简单

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

    【讨论】:

    • 我不确定要为上下文参数传递什么,当我使用毕加索时,我得到“NoClassDefFoundError”:protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView iv = (ImageView) findViewById(R.id.imageView1); Picasso.with(getApplicationContext()).load(R.drawable.appertizers_curly_twister_fries).into(iv); } 我应该为上下文添加什么?
    • 恐怕没有用,我的包中不存在 getActivity() 方法
    • 如果您在活动中使用毕加索,请使用此功能,如果您在片段中使用它,请使用 getActivity()。如果你在适配器中使用它,你应该在构造函数中传递上下文
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    相关资源
    最近更新 更多