java.lang.OutOfMemoryError:位图大小超过VM预算

时间:2010-10-18 04:59:55

标签: java listview bitmap out-of-memory

所以我的ListView有一个懒惰的图像加载器。我还使用this tutorial来更好地进行内存管理,并将SoftReference位图图像存储在我的ArrayList中。

我的ListView可以加载来自数据库的8张图像,然后一旦用户滚动到底部就会加载另外8张等等。当有大约35张图像或更少时,没有问题,但是更多和我的应用程序强制关闭OutOfMemoryError

我无法理解的是我在try catch中有我的代码:

try
{
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(image, 0, image.length, o);

    //Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;

    while(true)
    {
        if(width_tmp/2 < imageWidth || height_tmp/2 < imageHeight)
        {
            break;
        }

        width_tmp/=2;
        height_tmp/=2;
        scale++;
    }

    //Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length, o2);        
}
catch (Exception e)
{
    e.printStackTrace();
}

但是try catch块没有捕获OutOfMemory异常,根据我的理解,当应用程序内存不足时,应该清除SoftReference位图图像,停止OutOfMemory抛出异常。

我在这里做错了什么?

3 个答案:

答案 0 :(得分:9)

我想这篇文章可能会对你有帮助

//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //The new size we want to scale to
        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale*=2;
        }

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

答案 1 :(得分:4)

OutOfMemoryError错误也不例外,你不应该抓住它。

请参阅http://mindprod.com/jgloss/exception.html

编辑:已知问题请参阅this issue

答案 2 :(得分:0)

错误和异常是Throwable的子类。 错误应该是如此激烈,你不应该抓住它们。

但你可以抓住任何东西。

import javax.swing.*;  
import java.awt.event.*;
import java.awt.*; 

public class Main implements ActionListener {

  private static void createAndShowGUI() {
    Main app=new Main();
    // make frame..
    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame("I am a JFrame");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(20,30,300,120);
    frame.setLayout(null);

    //Create a split pane
    JSplitPane myPane = new JSplitPane();
    myPane.setOpaque(true);
    myPane.setDividerLocation(150);

    app.right = new JPanel();
    app.right.setBackground(new Color(255,0,0));
    app.left = new JPanel();
    app.left.setBackground(new Color(0,255,0));
    app.left.setLayout(null);
    myPane.setRightComponent(app.right);
    myPane.setLeftComponent(app.left);
    // make buttons
    app.butt1=new JButton("Red");
    app.butt2=new JButton("Blue");
    app.butt3=new JButton("Green");
    // add and size buttons
    app.left.add(app.butt1);
    app.butt1.setBounds(10,10, 100,20);
    app.left.add(app.butt2);
    app.butt2.setBounds(10,30, 100,20);
    app.left.add(app.butt3);
    app.butt3.setBounds(10,50, 100,20);
    // set up listener
    app.butt1.addActionListener(app);
    app.butt2.addActionListener(app);
    app.butt3.addActionListener(app);
    frame.setContentPane(myPane);
    frame.setVisible(true);              
  }

  public void actionPerformed(ActionEvent e)
  {
    // check which button and act accordingly
    if (e.getSource()==butt1)
      right.setBackground(new Color(255,0,0));
    if (e.getSource()==butt2)
      right.setBackground(new Color(0,0,255)); 
    if (e.getSource()==butt3)
      right.setBackground(new Color(0,255,0));
  }


  public static void main(String[] args) {
    // start off..
    try  {        
      UIManager.setLookAndFeel(   
      "javax.swing.plaf.metal.MetalLookAndFeel"   );   
    } 
    catch (Exception e) 
    {
      System.out.println("Cant get laf"); 
    }
    Object a[]= UIManager.getInstalledLookAndFeels();
    for (int i=0; i<a.length; i++)
      System.out.println(a[i]); 


    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }

  // application object fields    
  int clickCount=0;  

  JLabel label;
  JButton butt1;
  JButton butt2;
  JButton butt3;
  JPanel left;
  JPanel right;
}