加载图像ListView时的outOfMemory

时间:2014-04-03 10:04:47

标签: android out-of-memory

我从互联网上下载照片。在同一页面上有一张有18张照片(80x60像素~10kb)的网站。

所以我做了一个加载新图片的列表(sleduyuschuyuyu页面) 问题是当我加载三个或更多页面时,发生内存错误 问题是如何摆脱?

现在我构建了一个位图数组

for (Element titles : title) {
                    if (titles.children().hasClass("btl")){
                    m = new HashMap<String, Object>();
                    m.put(MyActivity.ATTRIBUTE_NAME_TEXT, titles.select("a[href]").attr("abs:href"));
                    Picasso p = Picasso.with(MyActivity.context);
                    m.put(MyActivity.ATTRIBUTE_NAME_PHOTO,Bitmap.createScaledBitmap(p.load(titles.select("img").attr("abs:src")).get(),80,60, true) );
                    data.add(m);
                    }
                }

并在适配器

@Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        final Map<String, Object> itemData = datas.get(position*2);

        final Map<String, Object> itemData2 = datas.get(position*2+1);
        Bitmap bitmap2 = null;
        Bitmap bitmap = (Bitmap) itemData.get("img");
        if(itemData2!=null)
            bitmap2 = (Bitmap) itemData2.get("img");

        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            rowView = inflater.inflate(R.layout.items, null, true);
            holder = new ViewHolder();
            holder.ivImage = (ImageView) rowView.findViewById(R.id.imageView);
            holder.ivImage2 = (ImageView) rowView.findViewById(R.id.imageView1);
            rowView.setTag(holder);
        } else {
            holder = (ViewHolder) rowView.getTag();
        }
        holder.ivImage.setImageBitmap(bitmap);
        holder.ivImage2.setImageBitmap(bitmap2);
        holder.ivImage.setTag(position*2);
        holder.ivImage2.setTag(position*2+1);
        holder.ivImage.setOnClickListener(this);
        holder.ivImage2.setOnClickListener(this);
        return rowView;
    }

我被提议将图像保存在缓存中并从那里加载它们但不知道如何操作。

请帮助

3 个答案:

答案 0 :(得分:1)

使用磁盘缓存...本文还提供了许多其他有用的加载位图的技巧 http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#disk-cache

答案 1 :(得分:0)

加载iomages的最佳方法是http://square.github.io/picasso/

上的毕加索库

答案 2 :(得分:0)

您将使用将图像解码为所需尺寸来阅读图像....

将图像转换为此方法.... 它用于绘制资源......

Bitmap bmap2 = decodeSampledBitmapFromResource(getResources(),
     R.drawable.hydrangeas, width, height);  


public static Bitmap decodeSampledBitmapFromResource(Resources res,
            int resId, int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

以下哪种方法可以通过使用流来解码....

public static Bitmap decodeSampledBitmapFromResource(InputStream in,
        int reqWidth, int reqHeight) throws IOException {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    in.mark(in.available());
    BitmapFactory.decodeStream(in, null, options);
    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);
    in.reset();
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeStream(in, null, options);
}

假设你将在all方法中失败你将尝试这个逻辑你只需要将这一行添加到你的mainfest文件......

您只需将此行添加到清单文件即可。它将为您的应用程序分配大内存。

    android:largeHeap="true"