滚动列表视图时出现内存不足的异常?[英] Out of Memory Exception while scroll Listview?

本文是小编为大家收集整理的关于滚动列表视图时出现内存不足的异常?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我通过许多资源推荐,但不能得到正确的答案,

我已经制作了自定义适配器以在ListView中查看图像.从存储卡中检索此图像.一切都很好,但是当我滚动ListView时,我得到了一个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是string的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;
}

}

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

推荐答案

使用此概念将帮助您,在此设置图像视图上的图像贝贝特图

之后
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并刷新ListView然后使用此概念

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

我希望它会帮助你.

am cam从开发人员网站获取帮助 Here

其他推荐答案

您正在使用

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

要加载位图.哪个可以将大位图加载到内存中,确保只需在所需的大小中加载它们.

关注加载大型位图

在AsyncTask中加载这些位图也是一个很好的做法.

for

处理位图关闭UI线程

其他推荐答案

of memory of memory of of ChineStive of ChineView,只有在查看并在未视图中释放它们时,才能在释放时加载 - 动态加载它们.

您还可以尝试在该适配器中结合一个视窗类.

本文地址:https://www.itbaoku.cn/post/102558.html

问题描述

I refered through many resources but can't get right answer,

I have made an custom adapter to view images in a listview. This images are retrieved from memory card. Everything runs fine but while i scroll through the listview i get an OutOfMemory Exception. I have posting the code using which i retrive images from 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());

        }
    }
}

here f is arraylist of string and i am passing it to an custom adapter following is the code for my custom adapter.

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

}

Any solution to my problem:

推荐答案

use this concept this will help you, After that set the imagebitmap on image view

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

If you want to make a small image from large image with height and width like 60 and 60 and scroll the listview fast then use this concept

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

I hope it will help you much.

You cam take help from developer site Here

其他推荐答案

You are using

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

to load bitmap.. which can load large bitmaps into the memory, make sure that you load them in required size only.

Follow Loading Large Bitmaps Efficiently

It is also a good practice to load these bitmaps in AsyncTask.

For that follow Processing Bitmaps Off the UI Thread

其他推荐答案

Out of memory means well you need to load images in the listview only when they're in view and release them when not in view - load them dynamically.

You can also try incorporating a ViewHolder class in that adapter.