0

所以我并没有真正得到这个错误消息右边的理由。我不确定为什么会发生这种情况,但我的猜测是这与大约有 50 个高质量的可绘制对象有关。在真正快速滚动时,应用程序崩溃。我觉得好像我正在缓解 ListView 和崩溃的最常见问题,例如使用 View Holders 以及只启动一次充气机。

Process: com.example.michael.myandroidappactivity, PID: 20103
java.lang.OutOfMemoryError
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)

这是代码

public class ImageAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Integer> imageIds;
private static LayoutInflater inflater;

public ImageAdapter(Context _context, ArrayList<Integer> _imageIds)
{
    context = _context;
    imageIds = _imageIds;
}

@Override
public int getCount()
{
    return imageIds.size();
}

@Override
public Object getItem(int position)
{
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

static class ViewHolder{
    ImageView img;
}

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

    ViewHolder holder = null;
    View rowView = null;

    if(rowView==null) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.listview_layout, parent, false);
        holder = new ViewHolder();
        holder.img = (ImageView) rowView.findViewById(R.id.flag);
        rowView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) rowView.getTag();
    }
    holder.img.setImageResource(imageIds.get(position));
    return rowView;
  }
}
4

4 回答 4

2

我真的不确定你想用你的适配器做什么,但你有一个逻辑错误/重言式。

您分配rowView给 null 并检查它是否null正确。它将永远存在null,您将永远不会最终使用您的ViewHolder.

于 2014-08-24T03:29:19.747 回答
0

除了@PeekaySwitch 强调的错误之外,我只想强调您实际上并不需要列表中的高清图片。当今设备常见的高清屏幕为1920x1080分辨率。这就是您可以在一个屏幕上显示的最高质量。但是考虑到屏幕的某些部分被其他图形组件占据,并且您有一个列表,因此您希望在每个屏幕上显示少量图像,这意味着每个图像的屏幕部分大大减少。您加载了一堆高清图像,但在屏幕上显示的最有可能< 1/10它的大小意味着不必要的内存使用。因此,我建议在处理图像时重新考虑这种方法。您可能想要创建一些缩略图或某物,以按列表的每个项目显示。例如,当用户点击它时的整个图像。此外,您可以考虑应用一些缓存机制,例如 android 中可用的 LRU。

于 2014-08-24T04:16:24.180 回答
0

您需要使用LRUCache缓存图像

这是一个众所周知的问题,因此有解决问题的良好做法。

Android-Universal-Image-Loader

可接受的 URI 示例:

String imageUri = "http://url/image.png"; // from Web
String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
String imageUri = "content://media/external/audio/albumart/13"; // from content provider
String imageUri = "assets://image.png"; // from assets
String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)

// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view 
// which implements ImageAware interface)

imageLoader.displayImage(imageUri, imageView);
于 2014-08-24T03:40:09.497 回答
0

Drawable 在资源中的压缩程度无关紧要,重要的是它们未压缩的大小。如上所述,您的图像尺寸为 500x726。对于 RGB,每张图像大约有 1MB 未压缩。

一些建议:

如果可能的话,缩小你的图像。我怀疑如果你使用 Photoshop、Gimp、Paint.Net 或 MSPaint 将图像缩放到 250x363,你会没事的。或者只看 ScalableDrawable 类。

避免在屏幕上保留对 Drawable 的任何引用。

在我的 ListView 中,我使用URLImageViewHelper来管理引用和 LRU 缓存。

于 2014-08-24T20:03:51.510 回答