滚动Listview时内存异常?

时间:2013-08-22 09:12:33

标签: android listview scroll

我提到了许多资源,但无法得到正确答案,

我制作了一个自定义适配器来查看列表视图中的图像。从存储卡中检索此图像。一切运行正常,但当我滚动列表视图时,我得到一个OutOfMemory异常。我发布了代码,使用它从sdcard中检索图像。

public void getFromSdcard() {

    File file = new File(
            android.os.Environment.getExternalStorageDirectory(),
            "Tiles/.NoMedia");

    if (file.isDirectory()) {
        listFile = file.listFiles();

        for (int i = 0; i < listFile.length; i++) {

            f.add(listFile[i].getAbsolutePath());

        }
    }
}

这里f是字符串的arraylist,我将它传递给自定义适配器,以下是我的自定义适配器的代码。

public class NewImageAdapter extends ArrayAdapter<Image> {

private ArrayList<Image> objects;
String packageName;
Activity act;

public NewImageAdapter(Activity context, int image_layout,
        ArrayList<Image> objects) {
    super(context, image_layout, objects);
    this.act = context;
    this.objects = objects;

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    View v = convertView;

    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.list_item, null);
    }

    Image i = objects.get(position);

    if (i != null) {
        ImageView iv = (ImageView) v.findViewById(R.id.imagemenu123);
        // TextView tv = (TextView) v.findViewById(R.id.commandText);
        if (iv != null) {

            Bitmap myBitmap = BitmapFactory.decodeFile(i.getImagePath());

            iv.setImageBitmap(myBitmap);
            // iv.setImageBitmap(i.getImageBitmap());
            // tv.setText("Tiles Images");
        }

    }
    return v;
}

}

我的问题的任何解决方案:

6 个答案:

答案 0 :(得分:5)

使用此概念这将对您有所帮助,之后在图像视图上设置imagebitmap

public static Bitmap convertBitmap(String path)   {

        Bitmap bitmap=null;
        BitmapFactory.Options bfOptions=new BitmapFactory.Options();
        bfOptions.inDither=false;                     //Disable Dithering mode
        bfOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
        bfOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
        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;
    }

如果你想从高度和宽度如60和60的大图像制作一个小图像并快速滚动列表视图,那么使用这个概念

public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
            int reqHeight) {

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

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

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bmp = BitmapFactory.decodeFile(path, options);
        return bmp;
        }

    public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {

        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
             }
         }
         return inSampleSize;
        }

我希望它会对你有所帮助。

您可以从开发者网站 Here

获取帮助

答案 1 :(得分:1)

您正在使用

Bitmap myBitmap = BitmapFactory.decodeFile(i.getImagePath())

加载位图..它可以将大位图加载到内存中,确保只加载所需的大小。

关注Loading Large Bitmaps Efficiently

AsyncTask中加载这些位图也是一种很好的做法。

对于以下Processing Bitmaps Off the UI Thread

答案 2 :(得分:0)

内存不足意味着你只需要在列表视图中加载图像并在视图中释放它们时 - 需要动态加载它们。

您还可以尝试在该适配器中合并ViewHolder类。

答案 3 :(得分:0)

这种情况正在发生,因为您正在创建位图。当app堆变满时,它会释放内存。 要解码您的位图,请使用此方法 - Out of memory while creating bitmaps on device

它肯定会帮助你。

答案 4 :(得分:0)

可能你可以试试这个:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
iv.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));

希望它能帮助!!

答案 5 :(得分:-1)

实际上我觉得最好的事情就是找出错误的共鸣。对于这个&#34; Out of Memroy&#34;就是当你滚动gcc正在分配内存时,即使你向下滚动,它也会为listview分配单独的内存,换句话说,你的内存会被浪费或者使用冗余。即使在位图中你也可以通过scaleize选项减少emeroy分配大小,但它是jsut永久解决方案的短期解决方案我发现通过查找大小,即d卡中的图像数量和滚动比较poistion,为每个列表视图创建一个视图数组当poistion等于视图的大小时视图的大小 - 1你已经达到了最终的网络唯一的memeroy已经被分配,如果你再次向上或向下滚动,你没有分配到separete memroy你已经到达视图数组的末尾,没有必要分配memeroy,因此解决了问题