Android 以编程方式添加到AnimationDrawable的图像会泄漏内存
我有一个android应用程序,有很多动画 当我以编程方式创建动画(使用Android 以编程方式添加到AnimationDrawable的图像会泄漏内存,android,memory-leaks,Android,Memory Leaks,我有一个android应用程序,有很多动画 当我以编程方式创建动画(使用AnimationDrawable)时,非java对象(如DDMS堆选项卡中显示的)会随着我加载的每个新动画而增长,即使在我的动画发布后也不会收缩 我对我编写的包装器对象中的每个AnimationDrawable对象只有一个引用,我通过重写finalize方法并确保调用它来验证该对象是否被释放 最终android停止加载图像,并将“内存不足”错误打印到日志中 有趣的是,这种情况只发生在某些设备(摩托罗拉Xoom、索尼Expe
AnimationDrawable
)时,非java对象(如DDMS堆选项卡中显示的)会随着我加载的每个新动画而增长,即使在我的动画发布后也不会收缩
我对我编写的包装器对象中的每个AnimationDrawable
对象只有一个引用,我通过重写finalize
方法并确保调用它来验证该对象是否被释放
最终android停止加载图像,并将“内存不足”错误打印到日志中
有趣的是,这种情况只发生在某些设备(摩托罗拉Xoom、索尼Experia)上,而在其他设备(如Galaxy S)上则没有发生
从我给出的设备示例中可以看出,这个问题不是特定的蜂窝或预蜂窝
我尝试过的一些事情:
myAnimation.addFrame(…)
这不是一个确切的答案,而是一个有助于找到确切泄漏发生地点的提示。在期望内存被回收后执行堆转储,并查看为什么您认为应该是死的对象仍然是活的
确保您获得了eclipse的内存分析器工具。(http://www.eclipse.org/mat/)可能有两个原因,第一个是在创建位图时,第二个是在将位图转换为BitmapDrawable时。正如我从您的评论
(新的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;
}
}
你能发布每个设备的总RAM吗?还有,你在说什么样的动画?你能发布一个初始化代码的例子吗?XOOM有1GB的RAM,我使用的是“大堆”在清单中的标记,Galaxy S有512MB,这
myAnimation.addFrame
的东西让我怀疑您可能没有按预期使用它。请发布一个小片段。在创建动画时,我只需使用:animation.addFrame(新的BitmapDrawable(currentFrameBitmap),milliPerFrame将所有BitmapDrawable添加到动画中;我也有同样的问题,有人想出过解决这个问题的办法吗?