2011-10-05 40 views
9

我有一个Android应用程序与大量的动画。图像添加到AnimationDrawable以编程方式泄漏内存

当我编程方式创建动画(使用AnimationDrawable)的非Java对象(如出现在DDMS堆标签),每一个新的动画我负载增长,永不退缩我的动画获得释放后也。

我只有一个引用来自我写的包装对象的每个AnimationDrawable对象,我通过覆盖finalize方法并确保它被调用来验证该对象。

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

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

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

一些我试过的东西:

  1. 调用每个帧的循环,我与当前动画完成后,但它似乎并没有帮助。
  2. 将null分配给AnimationDrawble对象
  3. 确保有相关的类持有参考动画绘制
  4. 确保一旦我注释掉myAnimation.addFrame(...)
+0

你能发布每个设备的总RAM吗?另外,你在谈论什么样的动画?你可以发布一个初始化代码的例子吗? –

+0

XOOM有1GB Ram,我使用清单中的“大堆”标志,Galaxy S有512MB – Gu1234

+0

这个'myAnimation.addFrame'让我怀疑你可能没有按照它的意图使用它。请发布一小段代码。 –

回答

0

问题消失无静态变量这不是一个确切的答案,而是一个有用的提示,可以找到发生确切泄漏的位置。希望回收记忆后,执行堆转储并查看您认为应该死的物体为什么仍然存在。

确保您获得了用于eclipse的内存分析工具。 (http://www.eclipse.org/mat/)

0

可能有两个可能的原因,第一个是在创建位图时,第二个是将位图转换为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; 
} 

}