Java 处理位图时出现内存不足异常
我正在开发一个应用程序,在这个应用程序中,我可以异步下载图像进行幻灯片放映。一个幻灯片包含10张幻灯片,因此打开幻灯片时会下载10张图像。在我大约滚动10-15个幻灯片之后,我开始在跟踪和应用程序崩溃中收到内存警告和以下异常 以下是跟踪:Java 处理位图时出现内存不足异常,java,android,Java,Android,我正在开发一个应用程序,在这个应用程序中,我可以异步下载图像进行幻灯片放映。一个幻灯片包含10张幻灯片,因此打开幻灯片时会下载10张图像。在我大约滚动10-15个幻灯片之后,我开始在跟踪和应用程序崩溃中收到内存警告和以下异常 以下是跟踪: 12-23 12:23:53.124: ERROR/dalvikvm-heap(3067): 45850-byte external allocation too large for this process. 12-23 12:23:53.134: ERRO
12-23 12:23:53.124: ERROR/dalvikvm-heap(3067): 45850-byte external allocation too large for this process.
12-23 12:23:53.134: ERROR/dalvikvm(3067): Out of memory: Heap Size=13127KB, Allocated=11913KB, Bitmap Size=11407KB
12-23 12:23:53.134: ERROR/GraphicsJNI(3067): VM won't let us allocate 45850 bytes
12-23 12:23:53.134: DEBUG/skia(3067): --- decoder->decode returned false
12-23 12:23:53.134: WARN/dalvikvm(3067): threadid=46: thread exiting with uncaught exception (group=0x400259f8)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): FATAL EXCEPTION: Thread-1016
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:468)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:332)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at com.nbcu.myApp.appsupport.AsyncImageLoader.loadImageFromUrl(AsyncImageLoader.java:98)
12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at com.nbcu.myApp.appsupport.AsyncImageLoader$2.run(AsyncImageLoader.java:70)
12-23 12:23:53.154: WARN/ActivityManager(96): Force finishing activity com.nbcu.myApp.activities/com.nbcu.myApp.controllers.StoriesListController
12-23 12:23:53.224: ERROR/dalvikvm-heap(3067): 45850-byte external allocation too large for this process.
12-23 12:23:53.234: DEBUG/SurfaceFlinger(96): Layer::setBuffers(this=0x2fabc0), pid=96, w=1, h=1
12-23 12:23:53.234: ERROR/dalvikvm(3067): Out of memory: Heap Size=13127KB, Allocated=11948KB, Bitmap Size=11407KB
12-23 12:23:53.234: ERROR/GraphicsJNI(3067): VM won't let us allocate 45850 bytes
12-23 12:23:53.234: ERROR/Error(3067): Message = java.lang.OutOfMemoryError: bitmap size exceeds VM budget
下载图像的代码为:
public void run() {
Looper.prepare();
for (int i = 0; i < slides.size(); i++) {
try {
final SlideShowItem story = slides.get(i);
if (story.getImage() == null) {
Drawable cachedImage = Utils.database.getRSSImage(Constants.StoriesTable, story.getItemId());
if (cachedImage != null) {
story.setImage(cachedImage);
} else {
cachedImage = asyncImageLoader.loadDrawable(story.getImagePath(), new ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
story.setImage(imageDrawable);
Utils.database.storeRSSItemImage(Constants.StoriesTable, imageDrawable, story.getItemId());
}
});
}
}
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
Looper.loop();
}
loadImageFromURL()的代码为:
下载图像后,图像将被缓存。我无法找到避免此异常的解决方法。原因可能是什么?我也尝试过在活动被销毁时将图像视图设置为空,但它对我没有任何帮助?感谢您的帮助。提前谢谢 Android是一种移动操作系统。它的内存有限,因此无法缓存所有幻灯片。size()。我想尺寸>15。例如,我正在运行一个以高清图像为标记的FastCV算法,250000 x 180000像素,如果我在pc上运行该程序,工作正常,如果我在手机上运行,则不会,因为内存不足
我认为你可以解决这个问题,只要10-15张照片,这取决于它们的大小。如果滚动,则在已经使用的内存中缓存一个新的。您应该使用一种经过调整的方法。我会一次使用3个图像,当前显示的图像和接下来的两个。这样,当用户查看image1时,image2和image3已经在内存中。当用户滑到image2时,应将image4加载到上一个image1缓冲区(image3仍在内存中)
我希望这有助于考虑将缓存的图像缩小到与它们一起使用的视图的大小。例如,您可以在
loadImageFromUrl(字符串url)
方法中使用以下方法:
// Determining the original size of the image:
BitmapFactory.Options optnsSizeOnly = new BitmapFactory.Options();
optnsSizeOnly.inJustDecodeBounds = true;
InputStream inputStreamSizeOnly = (java.io.InputStream) new java.net.URL(url).getContent();
BitmapFactory.decodeStream(inputStreamSizeOnly, null, optnsSizeOnly);
int widthOriginal = optnsSizeOnly.outWidth;
// Determining the scale ratio.
// Note, it's just an example, you should use more sophisticated algorithm:
int ratio = widhtOriginal / widthView; // widthView is supposed to be known
// Now loading the scaled image:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = ratio;
InputStream inputStream = (java.io.InputStream) new java.net.URL(url).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
解码功能是否保存流中的任何其他资源?错误到底在哪里抛出?
public static Drawable loadImageFromUrl(String url) {
Drawable image = null;
try {
InputStream in = (java.io.InputStream) new java.net.URL(url).getContent();
if (in != null) {
image = Drawable.createFromStream(in, "image");
}
in.close();
} catch (Exception ex) {
// ex.printStackTrace();
Log.v("Exception ", "Asyn Image.In LoadImageFromURL Message: " + ex.toString());
}
return image;
}
// Determining the original size of the image:
BitmapFactory.Options optnsSizeOnly = new BitmapFactory.Options();
optnsSizeOnly.inJustDecodeBounds = true;
InputStream inputStreamSizeOnly = (java.io.InputStream) new java.net.URL(url).getContent();
BitmapFactory.decodeStream(inputStreamSizeOnly, null, optnsSizeOnly);
int widthOriginal = optnsSizeOnly.outWidth;
// Determining the scale ratio.
// Note, it's just an example, you should use more sophisticated algorithm:
int ratio = widhtOriginal / widthView; // widthView is supposed to be known
// Now loading the scaled image:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = ratio;
InputStream inputStream = (java.io.InputStream) new java.net.URL(url).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);