内存不足异常未被捕获

时间:2013-04-24 06:25:43

标签: android out-of-memory

我可以选择在我的应用中将Bitmap保存到SD卡。
我正在使用AsyncTask方法进行保存。这是我在背景上做的事情

public File saveImageToExternalStorage(Bitmap image, String name) {
 String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + APP_PATH_SD_CARD + APP_THUMBNAIL_PATH_SD_CARD;

 try {
 File dir = new File(fullPath);
 if (!dir.exists()) {
 dir.mkdirs();
 }
 OutputStream fOut = null;
 File file = new File(fullPath, name.replaceAll("/", "").trim());
 file.createNewFile();
 fOut = new FileOutputStream(file);
 image.compress(Bitmap.CompressFormat.JPEG, 50, fOut);
 fOut.flush();
 fOut.close();
 MediaStore.Images.Media.insertImage(getApplicationContext().getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());

 return file;

 } catch (Exception e) {
 return null;
 }

如果我从此方法中获取null,则显示有关用户无法保存等信息。我虽然这应该足够了,但是我被这个方法的一个用户报告OutOfMemory崩溃了。堆栈跟踪:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:527)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:301)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:326)
at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:796)
at com.stancedcars.wallpapers.FullSelected.saveImageToExternalStorage(FullSelected.java:223)

我很乐意解决OutOfMemory问题,但Bitmap s尺寸大,图像分辨率高,我不想降低质量。更重要的是,我想知道为什么应用程序崩溃,即使它是在try catch?

3 个答案:

答案 0 :(得分:6)

你捕获了通用的Exception,而OutOfMemoryError是一个Error,它也是Throwable。

你得到了什么

java.lang.Object
   ↳    java.lang.Throwable
       ↳    java.lang.Error
           ↳    java.lang.VirtualMachineError
               ↳    java.lang.OutOfMemoryError

你能抓到什么

java.lang.Object
   ↳    java.lang.Throwable
       ↳    java.lang.Exception

所以为了捕捉所有可能的Throwables,你需要抓住

try {
     //...
} catch (Throwable e) {
    e.printStackTrace();
}

答案 1 :(得分:1)

使用catch OutOfMemoryError不是Exception!

try {
    // your code
} catch (OutOfMemoryError e) {
}

答案 2 :(得分:0)

一旦程序内存不足,就很难恢复。你需要仔细考虑如何在发生这种情况时尝试清理。例如,在saveImageToExternalStorage中,如果try / catch中发生异常,则不会清除fOut。所以你应该做像放

这样的事情
OutputStream fOut = null;
在try / catch之外的

,然后在try / catch的finally块中关闭它。并注意在最终块的捕获中进一步例外的可能性。