1

我参考了很多资源,但无法得到正确的答案,

我制作了一个自定义适配器来查看列表视图中的图像。此图像是从存储卡中检索的。一切运行良好,但是当我滚动浏览列表视图时,我得到了 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 是字符串的数组列表,我将它传递给自定义适配器下面是我的自定义适配器的代码。

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

}

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

4

6 回答 6

5

使用这个概念这将帮助你,然后在图像视图上设置图像位图

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

于 2013-08-22T09:19:57.047 回答
1

您正在使用

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

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

跟踪有效加载大型位图

将这些位图加载到AsyncTask.

为此,请按照UI 线程处理位图

于 2013-08-22T09:16:12.560 回答
0

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

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

于 2013-08-22T09:16:20.327 回答
0

发生这种情况是因为您正在创建位图。当应用程序堆满时,它会耗尽内存。要解码您的位图,请使用此方法 - 在设备上创建位图时内存不足

它肯定会帮助你。

于 2013-08-22T09:16:48.430 回答
0

也许你可以试试这个:

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

希望能帮助到你!!

于 2013-08-22T09:17:10.487 回答
-1

其实我认为最好的事情是找到错误的原因。这个“Out of Memroy”的主要原因是,当你滚动 gcc 分配内存时,即使你从下向上滚动,它也会为 listview 分配单独的内存,换句话说,你的内存被浪费或冗余使用了。即使在位图中,您也可以通过 scalesize 选项减少 emeroy 分配大小,但它是永久解决方案的短期解决方案,我发现通过找出大小(即 d 卡中的图像数量以及滚动比较位置)为每个列表视图创建一个视图数组当 poistion 等于 view-1 的大小时,视图的大小已达到末端网络唯一内存已分配,如果您再次向上或向下滚动,则不会在列表视图中分配单独的内存,因为您已到达视图数组的末尾,不再需要分配内存,因此问题解决了

于 2014-04-13T13:33:15.983 回答