Java 加载照片时位图OutOfMemoryException
在我的应用程序中,用户可以启动相机并拍摄照片,然后将其保存到自定义文件夹中。然后,他们可以重新启动相机拍摄另一张照片等,这样最终用户可以拍摄多张照片 我遇到的问题是,在我的图库中,当我尝试将所有图片加载到位图以放置在imageview中时,我得到一个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
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))