添加到AnimationDrawable以编程方式泄漏内存的图像

我有一个Android应用程序与大量的animation。

当我以编程方式创buildanimation(使用AnimationDrawable )时, 非Java对象 (如出现在DDMS堆选项卡中)随着我加载的每个新animation而增长,即使在我的animation发布后也不会缩回。

我只有一个从我写的包装对象的每个AnimationDrawable对象的引用,我validation了这个对象获取通过重写finalize方法,并确保它被调用释放。

最终,android会停止加载图像,并将“内存不足”错误打印到日志中。

有趣的是,这只发生在一些设备(摩托罗拉Xoom,索尼Experia),而不是在其他人(如Galaxy S)。

这个问题不是特定的蜂窝或蜂窝前蜂窝,你可以从我给出的设备示例中看到。

我尝试过的一些事情:

  1. 在完成当前animation之后调用每个帧的回收,但似乎没有帮助。
  2. 为AnimationDrawble对象分配null
  3. 确保没有与持有引用animation可绘制的类相关的静态variables
  4. 确保问题消失后,我注释掉myAnimation.addFrame(...)

Solutions Collecting From Web of "添加到AnimationDrawable以编程方式泄漏内存的图像"

这不是一个确切的答案,而是一个有用的提示,find确切的泄漏发生的地方。 当你期待你的回忆被回收后,执行一个堆转储,看看你认为应该死的物体为什么还活着。

确保你得到了eclipse的内存分析工具。 (http://www.eclipse.org/mat/)

可能有两个可能的原因,第一个是在创build位图时,第二个是在将位图转换为BitmapDrawable时。 正如我从你的评论(new BitmapDrawable(currentFrameBitmap)现在可以看到这种方法更好地折旧使用BitmapDrawable(getResources(),currentFrameBitmap)没有资源引用,位图可能无法正确呈现,即使正确缩放。你可以正确地缩放它。

 public class BitmapDecoderHelper { private Context context; public BitmapDecoderHelper(Context context){ this.context = context; } public int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; Log.d("height reqheight width reqwidth", height+"//"+reqHeight+"//"+width+"///"+reqWidth); if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize; } public Bitmap decodeSampledBitmapFromResource(String filePath, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); Log.d("options sample size", options.inSampleSize+"///"); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; // out of memory occured easily need to catch and test the things. return BitmapFactory.decodeFile(filePath, options); } public int getPixels(int dimensions){ Resources r = context.getResources(); int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensions, r.getDisplayMetrics()); return px; } public String getFilePath(Uri selectedImage){ String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String filePath = cursor.getString(columnIndex); cursor.close(); return filePath; } }