Java 加载照片时位图OutOfMemoryException

Java 加载照片时位图OutOfMemoryException,java,android,bitmap,out-of-memory,Java,Android,Bitmap,Out Of Memory,在我的应用程序中,用户可以启动相机并拍摄照片,然后将其保存到自定义文件夹中。然后,他们可以重新启动相机拍摄另一张照片等,这样最终用户可以拍摄多张照片 我遇到的问题是,在我的图库中,当我尝试将所有图片加载到位图以放置在imageview中时,我得到一个java.lang.OutOfMemoryError异常。我读过一些关于内存管理的书,但我想我已经弄明白了。到目前为止,我的代码是这样的: File folder = new File(dir + "/");//contains anything f

在我的应用程序中,用户可以启动相机并拍摄照片,然后将其保存到自定义文件夹中。然后,他们可以重新启动相机拍摄另一张照片等,这样最终用户可以拍摄多张照片

我遇到的问题是,在我的图库中,当我尝试将所有图片加载到位图以放置在imageview中时,我得到一个
java.lang.OutOfMemoryError
异常。我读过一些关于内存管理的书,但我想我已经弄明白了。到目前为止,我的代码是这样的:

File folder = new File(dir + "/");//contains anything from 1-20 pictures
File[] allPics = folder.listFiles();

private Bitmap[] thumbnails;
private String[] arrPath;

//load all the files into bitmaps to assign to my gridview adapter
for (int i = 0; i < allPics.length; i++) {
            thumbnails[i] = BitmapFactory.decodeFile(allPics[i].getAbsolutePath());//where the exception is thrown

            arrPath[i]= allPics[i].getAbsolutePath();
        }

这里很简单。你正在同时解码一堆照片。不要那样做。如果数字较高,即使是高端设备上也没有足够的内存。相反,保存位图的位置,只在getView中放大位图。如果这还不够,您可以使用LRU缓存并将最后N个位图存储在内存中。但是你不能只是膨胀大量的图像。

这里很简单。你正在同时解码一堆照片。不要那样做。如果数字较高,即使是高端设备上也没有足够的内存。相反,保存位图的位置,只在getView中放大位图。如果这还不够,您可以使用LRU缓存并将最后N个位图存储在内存中。但是你不能仅仅夸大大量图片。

Android中的内存管理并不容易。您必须缓存图像并使用
LRUCache
正确管理它们,即使这样您也会遇到麻烦。使用毕加索图像加载器,它非常简单,而且会帮你省去很多头痛。我会仔细研究一下。很可能照片比你正在应用它的
ImageView
(或任何东西)要大得多。使用
BitmapFactory.Options
inSampleSize
加载大小更合适的内容。一个好的图书馆会帮你做到这一点;我想毕加索会的。我不会说毕加索的坏话,但我要说的是——不要直接把图书馆当作神奇的解决方案。了解它为你做了什么以及为什么这样做,这样你就可以预测未来这些类型的问题(甚至评估自己做是否更好)。只是盲目地使用一个库,因为你被告知它可以处理你的问题,这是一个很好的方法来制造混乱的代码。您必须缓存图像并使用
LRUCache
正确管理它们,即使这样您也会遇到麻烦。使用毕加索图像加载器,它非常简单,而且会帮你省去很多头痛。我会仔细研究一下。很可能照片比你正在应用它的
ImageView
(或任何东西)要大得多。使用
BitmapFactory.Options
inSampleSize
加载大小更合适的内容。一个好的图书馆会帮你做到这一点;我想毕加索会的。我不会说毕加索的坏话,但我要说的是——不要直接把图书馆当作神奇的解决方案。了解它为你做了什么以及为什么这样做,这样你就可以预测未来这些类型的问题(甚至评估自己做是否更好)。只是盲目地使用库,因为你被告知它可以处理你的问题,这是一种很好的方法,可以产生混乱的代码。那么,将相机生成的位图保存在db中会更好吗?我当时正在考虑将用户限制为仅5张图片,这与图像的生成方式无关。一旦它们被解压,内存中的大小就成了问题。如果图像的像素为X宽Y高,则未压缩的总内存为4*X*Y字节。但是,通过控制一次内存中有多少图像,您只需要固定的内存量,而不是所有图像的总量。那么将相机生成的位图保存在db中会更好吗?我当时正在考虑将用户限制为仅5张图片,这与图像的生成方式无关。一旦它们被解压,内存中的大小就成了问题。如果图像的像素为X宽Y高,则未压缩的总内存为4*X*Y字节。但通过控制一次内存中的图像数量,您只需要固定的内存量,而不是所有图像的总量。
pcemobileapp E/AndroidRuntime: FATAL EXCEPTION: main
 Process: pcemobileapp, PID: 7069
 java.lang.OutOfMemoryError
     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
     at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:719)
     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:695)
     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:452)
     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:491)
     at pcemobileapp.CustomGalleryActivity.onCreate(CustomGalleryActivity.java:65)
     at android.app.Activity.performCreate(Activity.java:5459)
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2458)
     at android.app.ActivityThread.access$900(ActivityThread.java:172)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1305)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:146)
     at android.app.ActivityThread.main(ActivityThread.java:5598)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
     at dalvik.system.NativeStart.main(Native Method))