我已经搜索了几小时关于内存泄漏的问题,我似乎无法解决我的问题。经过9次旋转后,我的应用程序崩溃并出现OutOfMemory错误。我的应用程序中有Bitmaps的Bitmaps和Drawables。我已经尝试将代码移除到drawables的回调,我已经尝试将所有Bitmaps设置为null以及手动调用垃圾收集器。我在onSaveInstanceState()方法中拥有所有这些代码,因为我认为只要屏幕发生变化并且在销毁视图之前就会调用它。这些解决方案都不起作用。
我得到了一些结果,Bitmaps变为null,但是在另一个内存泄漏之前只增加了另外9个屏幕旋转。我的泄漏在哪里?我究竟做错了什么?我的印象是,当一个屏幕旋转时,一切都被破坏并重新创建,这显然是错误的。
我不想发布我的代码,因为A.有很多它和B.它接近完成,所以成为公司秘密本身。如果有什么东西你必须绝对看到解决这个问题,那么我会发布它。我想我只需要一个非常好的解释,当屏幕旋转时实际发生了什么,以及如何正确处理位图和drawables。注意:如果我离开应用程序然后返回,则不会弹出此错误,只有在屏幕旋转时调整视图大小时才会出现此错误。
我有大约7个位图和7个drawable,都是在启动时创建的,并在屏幕旋转时调整大小。多次这样做会阻止应用程序。
一些简化的代码: 我如何设置一个可绘制的位图。这个也设置为ClipDrawable:
//Full Bar
colorbarMap = BitmapFactory.decodeResource(res, R.drawable.colorbar);
colorbarDraw = new BitmapDrawable(res, colorbarMap);
colorbarDraw.setBounds(barX, barY, barX2, barY2);
colorbarClip = new ClipDrawable(colorbarDraw, Gravity.BOTTOM, ClipDrawable.VERTICAL);
colorbarClip.setBounds(barX, barY, barX2, barY2);
colorbarClip.setLevel(currentLevel);
//Empty Bar
colorbaremptyMap = BitmapFactory.decodeResource(res, R.drawable.colorempty);
colorbaremptyDraw = new BitmapDrawable(res, colorbaremptyMap);
colorbaremptyDraw.setBounds(barX, barY, barX2, barY2);
上面的代码在视图初始化时基于以下代码运行一次:
private void init(){
//System
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
res = getResources();
options = new BitmapFactory.Options();
viewTreeObserver = getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
view_width = getWidth();
view_height = getHeight();
afterLayout();
}
});
}
}
第一个代码段在以下方法下运行:afterLayout()
此后没有用位图完成任务。基于视图宽度和高度,使用x和y位置初始化每个位图。使用矩形编辑该位置以设置其边界,例如移动对象。
答案 0 :(得分:0)
如果要显示的位图小于使用此位图,或者您不需要高分辨率图像
bitmapOption = new BitmapFactory.Options();
bitmapOption.inScaled = true;
bitmapOption.inSampleSize = 2;
imageBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), bitmapOption);
这会减少位图的大小,看看秃头家伙的解释
将你的位图加载代码放入try finally块并在最后使用它
try {
...
}finally {
if (imageBitmap != null) {
//recycle the bitmap to improve performance and avoid OO Exception
imageBitmap.recycle();
imageBitmap = null;
}
}
每当调用GC时,这将回收图像占用的位图空间