简体   繁体   English

未捕获内存不足异常

[英]Out of memory exception not caught

I have option to save Bitmap to sdcard in my app. 我可以选择将Bitmap保存到我的应用程序中的sdcard中。
I am doing saving in AsyncTask method. 我正在保存AsyncTask方法。 here is what i do on background 这是我在背景上所做的

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

I am displaying some information about failing to save and etc for user if I get null from this method. 如果从此方法中获取空值,我将向用户显示有关无法保存等信息。 I though this should be sufficient, yet I got reported OutOfMemory crash by one user from this method. 我虽然这应该足够,但是我从一个方法报告了一个用户报告OutOfMemory崩溃。 Stacktrace: 堆栈跟踪:

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)

I would love to solve OutOfMemory issue, but Bitmap s are heavy in size, high resolution images, I wouldn't want to reduce quality. 我很想解决OutOfMemory问题,但是Bitmap的尺寸大,分辨率高,我不想降低质量。 More importantly I would like to know why the app crashed even though it was in try catch ? 更重要的是,我想知道为什么即使尝试捕获该应用程序也会崩溃?

You catch the generic Exception, while OutOfMemoryError is an Error, which is Throwable as well. 您捕获了通用的Exception,而OutOfMemoryError是一个Error,这也是Throwable的。

What you got 你有什么

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

What you can catch 你能抓到什么

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

So to catch all possible Throwables, you need to catch 因此,要捕获所有可能的Throwables,您需要捕获

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

Use catch OutOfMemoryError not Exception! 使用catch OutOfMemoryError不是异常!

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

Once a program goes out of memory it can be hard for it to recover. 一旦程序内存不足,就很难恢复。 You need to think carefully about how to try and clean up when that happens. 您需要仔细考虑如何在发生这种情况时尝试进行清理。 For example, in your saveImageToExternalStorage, it doesn't clean up the fOut if an exception occurs inside your try/catch. 例如,在您的saveImageToExternalStorage中,如果在try / catch中发生异常,则不会清除fOut。 So you should do things like put 所以你应该做一些像放

OutputStream fOut = null;

outside the try/catch, and then close it in a finally block of the try/catch. 在try / catch外部,然后在try / catch的finally块中将其关闭。 And pay attention to the possibility of further exceptions in the catch of finally blocks. 并注意在finally块捕获中可能进一步出现例外的可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM