调整一个 ImageView 后无限 GC_FOR_ALLOC
Endless GC_FOR_ALLOC after resize one ImageView
我在我的日志猫中得到了无穷无尽的 GC_FOR_ALLOC,如下所示:
32ms, total 32ms
07-01 12:23:28.946 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 32% free 18349K/26896K, paused 15ms, total 15ms
07-01 12:23:29.116 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3006K, 32% free 18381K/26896K, paused 20ms, total 20ms
07-01 12:23:29.376 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4671K, 33% free 18284K/26896K, paused 17ms, total 17ms
07-01 12:23:29.496 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1898K, 32% free 18379K/26896K, paused 18ms, total 18ms
07-01 12:23:29.606 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 32% free 18349K/26896K, paused 17ms, total 17ms
07-01 12:23:29.806 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3006K, 32% free 18381K/26896K, paused 15ms, total 16ms
07-01 12:23:30.086 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4671K, 33% free 18283K/26896K, paused 17ms, total 19ms
07-01 12:23:30.206 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 2035K, 33% free 18242K/26896K, paused 14ms, total 15ms
07-01 12:23:30.316 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 33% free 18212K/26896K, paused 11ms, total 12ms
07-01 12:23:30.486 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3007K, 33% free 18245K/26896K, paused 17ms, total 17ms
07-01 12:23:30.736 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4359K, 33% free 18146K/26896K, paused 17ms, total 18ms
07-01 12:23:30.856 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1898K, 33% free 18242K/26896K, paused 16ms, total 17ms
07-01 12:23:30.966 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 33% free 18212K/26896K, paused 15ms, total 15ms
07-01 12:23:31.136 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3006K, 33% free 18245K/26896K, paused 20ms, total 21ms
07-01 12:23:31.396 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4359K, 33% free 18146K/26896K, paused 17ms, total 17ms
07-01 12:23:31.516 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1898K, 33% free 18242K/26896K, paused 17ms, total 17ms
07-01 12:23:31.636 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 33% free 18212K/26896K, paused 19ms, total 20ms
07-01 12:23:31.816 14905-14905/com.dodosocial.lowon
追查错误后,我发现这是因为我以编程方式修改了 ImageView 的高度。
这是我使用的代码:
MyActivity.java
private ImageView mImageUserProfile;
private Bitmap mBitmapIcon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageUserProfile = (ImageView)findViewById(R.id.login_icon);
mImageUserProfile.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mBitmapIcon = CommUtils.getUserProfileBitmap();
if(mBitmapIcon!=null) {
setupIcon();
}
}
});
}
private void setupIcon() {
int bmHeight = mBitmapIcon.getHeight();
int bmWidth = mBitmapIcon.getWidth();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)mImageUserProfile.getLayoutParams();
layoutParams.height = layoutParams.width*bmHeight/bmWidth;
mImageUserProfile.setLayoutParams(layoutParams);
mImageUserProfile.setImageBitmap(mBitmapIcon);
}
像下面这样去掉高度改变的代码后,GC_FOR_ALLOC的东西就没有了
private void setupIcon() {
int bmHeight = mBitmapIcon.getHeight();
int bmWidth = mBitmapIcon.getWidth();
/*
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)mImageUserProfile.getLayoutParams();
layoutParams.height = layoutParams.width*bmHeight/bmWidth;
mImageUserProfile.setLayoutParams(layoutParams);
*/
mImageUserProfile.setImageBitmap(mBitmapIcon);
}
正如@GabeSechan 在对您的问题的评论中所说,您正在导致无限循环,因为您没有删除布局侦听器。
通过更改 ImageView
的高度,您可以使其测量无效,这会导致布局通过。系统将重新布局,然后重新触发 GlobalLayoutListener
,然后重新触发您的代码以更改高度...这会导致另一个布局...等
如果您只记得在更改布局之前删除侦听器,您应该没问题。
使用你的代码看起来像这样:
mImageUserProfile
.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mBitmapIcon = CommUtils.getUserProfileBitmap();
if(mBitmapIcon!=null) {
mImageUserProfile
.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
setupIcon();
}
}
});
我在我的日志猫中得到了无穷无尽的 GC_FOR_ALLOC,如下所示:
32ms, total 32ms
07-01 12:23:28.946 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 32% free 18349K/26896K, paused 15ms, total 15ms
07-01 12:23:29.116 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3006K, 32% free 18381K/26896K, paused 20ms, total 20ms
07-01 12:23:29.376 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4671K, 33% free 18284K/26896K, paused 17ms, total 17ms
07-01 12:23:29.496 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1898K, 32% free 18379K/26896K, paused 18ms, total 18ms
07-01 12:23:29.606 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 32% free 18349K/26896K, paused 17ms, total 17ms
07-01 12:23:29.806 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3006K, 32% free 18381K/26896K, paused 15ms, total 16ms
07-01 12:23:30.086 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4671K, 33% free 18283K/26896K, paused 17ms, total 19ms
07-01 12:23:30.206 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 2035K, 33% free 18242K/26896K, paused 14ms, total 15ms
07-01 12:23:30.316 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 33% free 18212K/26896K, paused 11ms, total 12ms
07-01 12:23:30.486 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3007K, 33% free 18245K/26896K, paused 17ms, total 17ms
07-01 12:23:30.736 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4359K, 33% free 18146K/26896K, paused 17ms, total 18ms
07-01 12:23:30.856 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1898K, 33% free 18242K/26896K, paused 16ms, total 17ms
07-01 12:23:30.966 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 33% free 18212K/26896K, paused 15ms, total 15ms
07-01 12:23:31.136 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 3006K, 33% free 18245K/26896K, paused 20ms, total 21ms
07-01 12:23:31.396 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 4359K, 33% free 18146K/26896K, paused 17ms, total 17ms
07-01 12:23:31.516 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1898K, 33% free 18242K/26896K, paused 17ms, total 17ms
07-01 12:23:31.636 14905-14905/com.dodosocial.lowongan D/dalvikvm﹕ GC_FOR_ALLOC freed 1994K, 33% free 18212K/26896K, paused 19ms, total 20ms
07-01 12:23:31.816 14905-14905/com.dodosocial.lowon
追查错误后,我发现这是因为我以编程方式修改了 ImageView 的高度。
这是我使用的代码:
MyActivity.java
private ImageView mImageUserProfile;
private Bitmap mBitmapIcon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageUserProfile = (ImageView)findViewById(R.id.login_icon);
mImageUserProfile.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mBitmapIcon = CommUtils.getUserProfileBitmap();
if(mBitmapIcon!=null) {
setupIcon();
}
}
});
}
private void setupIcon() {
int bmHeight = mBitmapIcon.getHeight();
int bmWidth = mBitmapIcon.getWidth();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)mImageUserProfile.getLayoutParams();
layoutParams.height = layoutParams.width*bmHeight/bmWidth;
mImageUserProfile.setLayoutParams(layoutParams);
mImageUserProfile.setImageBitmap(mBitmapIcon);
}
像下面这样去掉高度改变的代码后,GC_FOR_ALLOC的东西就没有了
private void setupIcon() {
int bmHeight = mBitmapIcon.getHeight();
int bmWidth = mBitmapIcon.getWidth();
/*
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)mImageUserProfile.getLayoutParams();
layoutParams.height = layoutParams.width*bmHeight/bmWidth;
mImageUserProfile.setLayoutParams(layoutParams);
*/
mImageUserProfile.setImageBitmap(mBitmapIcon);
}
正如@GabeSechan 在对您的问题的评论中所说,您正在导致无限循环,因为您没有删除布局侦听器。
通过更改 ImageView
的高度,您可以使其测量无效,这会导致布局通过。系统将重新布局,然后重新触发 GlobalLayoutListener
,然后重新触发您的代码以更改高度...这会导致另一个布局...等
如果您只记得在更改布局之前删除侦听器,您应该没问题。
使用你的代码看起来像这样:
mImageUserProfile
.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mBitmapIcon = CommUtils.getUserProfileBitmap();
if(mBitmapIcon!=null) {
mImageUserProfile
.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
setupIcon();
}
}
});