我有一个拥有大量动画的Android应用程序。
当我以编程方式创建动画时(使用AnimationDrawable
),非java对象(如DDMS堆标签中所示)随着我加载的每个新动画而增长,即使在我加载后也不会缩小动画发布。
我对我编写的包装器对象中的每个AnimationDrawable
对象只有一个引用,我通过覆盖finalize
方法并确保它被调用来验证此对象是否被释放。
最终android停止加载图像并将“内存不足”错误打印到日志中。
有趣的是,这种情况只发生在某些设备(Motorola Xoom,Sony Experia)而其他设备(例如Galaxy S)中。
从我给出的设备示例中可以看出,这个问题不是特定的Honeycomb或pre-Honeycomb。
我尝试过的一些事情:
myAnimation.addFrame(...)
答案 0 :(得分:0)
这不是一个确切的答案,而是一个有用的提示,可以找到确切泄漏发生的位置。在您希望回收内存之后执行堆转储,并查看为什么您认为应该死的对象仍然存在。
确保获得eclipse的内存分析工具。 (http://www.eclipse.org/mat/)
答案 1 :(得分: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;
}
}