所以我的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
抛出异常。
我在这里做错了什么?
答案 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)
答案 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;
}