Android应用程序在三星Galaxy S3上崩溃(内存不足错误)

我有一个Android应用程序,需要一些照片,重新resize,并将它们发送到后端服务器。 除了三星Galaxy S3以外,这款应用程序在所有其他手机(姜饼和冰淇淋三明治)上都可以正常工作。 无论何时拍摄照片并尝试重新resize,都会耗尽内存。 最初我以为这是一个问题,重新resize的部分,我用insamplesize实现了位图对象,并尝试了一切,但仍然保持崩溃。 然后,我意识到,当应用程序首先启动时,它正在使用了大量的内存。 在HTC和所有其他手机上,当我的应用程序启动时,它使用了大约4 MB,但在Galaxy S3上,它消耗了大约30 MG – 几乎10倍。 我似乎无法弄清楚是什么会导致它消耗更多的内存。 我正在回收所有的对象和布局(我认为)。 这里是我必须调整图像的代码:

public static void resizeImage(String pathOfInputImage, String pathOfOutputImage) { try { int inWidth = 0; int inHeight = 0; float factor; InputStream in = new FileInputStream(pathOfInputImage); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, options); inWidth = options.outWidth; inHeight = options.outHeight; in.close(); in = null; options = null; if (inWidth > inHeight) { factor = (float) inHeight / 480; } else { factor = (float) inWidth / 480; } options = new BitmapFactory.Options(); Bitmap roughBitmap; if(Build.VERSION.SDK_INT < 12) { System.gc(); } try { in = new FileInputStream(pathOfInputImage); options.inSampleSize = 4; roughBitmap = BitmapFactory.decodeStream(in, null, options); } catch (OutOfMemoryError e) { roughBitmap = Utils.fetchRoughBitmap(pathOfInputImage, factor); } finally { roughBitmap = Utils.fetchRoughBitmap(pathOfInputImage, factor); } in.close(); in = null; boolean rotate = false; Bitmap rotatedBitmap = null; if (isNeedToRotate(pathOfInputImage)) { rotate = true; Matrix m = new Matrix(); m.postRotate(90); try { rotatedBitmap = Bitmap.createBitmap(roughBitmap, 0, 0, roughBitmap.getWidth(), roughBitmap.getHeight(), m, true); } catch (OutOfMemoryError e) { rotatedBitmap = Bitmap.createBitmap(roughBitmap, 0, 0, roughBitmap.getWidth()/2, roughBitmap.getHeight()/2, m, true); } } if (rotate) { Utils.log(TAG, "Rotate Invoked :------->"); int temp = inHeight; inHeight = inWidth; inWidth = temp; } options.inSampleSize = Math.round(factor); float dstWidth = (int) inWidth / factor; float dstHeight = (int) inHeight / factor; Bitmap resizedBitmap; if (rotate) { try { resizedBitmap = Bitmap.createScaledBitmap(rotatedBitmap, (int) dstWidth, (int) dstHeight, true); } catch (OutOfMemoryError e) { resizedBitmap = Bitmap.createScaledBitmap(rotatedBitmap, (int) dstWidth/2, (int) dstHeight/2, true); } } else { try { resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) dstWidth, (int) dstHeight, true); } catch (OutOfMemoryError e) { resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) dstWidth/2, (int) dstHeight/2, true); } } try { FileOutputStream out = new FileOutputStream(pathOfOutputImage); resizedBitmap.compress(Bitmap.CompressFormat.PNG, 80, out); } catch (Exception e) { Utils.log("Image", e.getMessage() + e); } //Free up the memory. roughBitmap.recycle(); resizedBitmap.recycle(); if (rotatedBitmap != null) { rotatedBitmap.recycle(); } } catch (IOException e) { Utils.log("Image", e.getMessage() + e); } } private static Bitmap fetchRoughBitmap(String pathOfInputImage, float factor) { Bitmap roughBitmap = null; try { FileInputStream in = new FileInputStream(pathOfInputImage); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = Math.round(factor); roughBitmap = BitmapFactory.decodeStream(in, null, options); return roughBitmap; } catch (OutOfMemoryError mem_error) { return Utils.fetchRoughBitmap(pathOfInputImage, factor+1); } catch (FileNotFoundException e) { //return Utils.fetchRoughBitmap(pathOfInputImage, factor+1); return roughBitmap; } } 

这段代码工作正常,因为我通过recursion循环运行它,直到它没有用完内存,但那么我的结果图像只有约300×300像素,我需要它至less640x480。 我的问题是:

  1. 谁能告诉我为什么银河S3使用高达90%的内存时,它首次加载我的应用程序,而不是60%的HTC手机。
  2. 在我的应用程序内存不足的重新resize的代码中做了什么错误。

任何帮助将不胜感激,因为我已经在这个问题上花了3天:-(。

Solutions Collecting From Web of "Android应用程序在三星Galaxy S3上崩溃(内存不足错误)"

呃…我知道这是一个古老的问题,但这是我的想法。

Galaxy S3使用xhdpi密度,因此在启动时分配更大的堆大小(据我所知,32mb)

但是如果您的res目录中没有任何xhdpi资源,则会调用任何可绘制的默认图像或最接近xhdpi密度的hdpi。

然后,它将扩大图像,以适应它的需求,并在这个阶段扩大图像将占用大量的内存,(可能)导致内存不足的问题。

您可以通过启用屏幕兼容模式来解决此问题,也可以创build(如果默认情况下不存在)drawable-xhdpi,为xhdpi设备(如Galaxy S3)提供适当的资源

哇。 现在我们已经在S3上挣扎了这个“内存不足”的问题。 最后,在这个线程中应用了其中的一种技术。

在我们的应用程序中,我们有drawable-hdpi拥有应用程序的所有图像。 在大多数手机上,我们没有问题。 在S3上,应用程序会占用两倍的内存,然后遇到内存不足的问题。

我刚创build了drawable-xhdpi文件夹,其内容与drawable-hdpi文件夹相同,并在S3上运行。 立即注意到内存占用是1/2,没有内存不足的问题。

这是一个令人沮丧的经验。 希望其他人知道寻找这个线程,并节省几个小时的排除。

谢谢

我自己解决了这个问题。 内存不足的应用程序无需对上述代码进行任何操作。 我添加了MAT,并且看到位图对象在以前的视图中保持活动状态。 所以我从视图中删除了graphics,并解决了内存问题。

 I overwrote the onDestroy method and added the following line: layout.setBackgroundDrawable(null);. Please let me know if this worked or didn't work for you. 

– user881148

酷,它为我工作…一点点在布局上添加背景图片。 而不是使用BitmapDrawables或位图我从位图转换后使用Drawables。

 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.outerspace); Drawable bitDraw = new BitmapDrawable(getResources(), bitmap); main.setBackgroundDrawable(bitDraw); 

我的问题是,正在所有设备的S3期待(这是讨厌)。 但该应用程序已经启动并正在运行! 感谢名单… user881148