记属性动画监听器--AnimatorListenerAdapter导致的内存泄露
·
在使用AS的Profiler进行内存分析时,发现打开关闭activity会导致内存增长,并且不会下降,Dump Java heap 发现出现内存泄露:

观察引用情况(勾选 Show nearest GC root only):

jump tosource 发现是属性动画监听器出现内存泄露:
alphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
setAlpha(1);
}
});
发现是这个alphaAnimator没有释放导致的内存泄露,解决办法:
将AnimatorListenerAdapter改写为静态内部类,并且使用弱引用,这样alphaAnimator就不会一直引用 RelativeLayout 导致内存泄露。
//改写为静态内部类,并使用弱引用
static class AnimUpdateListener extends AnimatorListenerAdapter{
WeakReference<RelativeLayout> mWeakReference;
public AnimUpdateListener(RelativeLayout relativeLayout){
mWeakReference= new WeakReference<>(relativeLayout);
}
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
mWeakReference.get().setAlpha(1);
}
}
alphaAnimator.addListener(new AnimUpdateListener(this));
原因分析:在start 动画时源码如下
@Override
public void start() {
AnimationHandler.getInstance().autoCancelBasedOn(this);
if (DBG) {
Log.d(LOG_TAG, "Anim target, duration: " + getTarget() + ", " + getDuration());
for (int i = 0; i < mValues.length; ++i) {
PropertyValuesHolder pvh = mValues[i];
Log.d(LOG_TAG, " Values[" + i + "]: " +
pvh.getPropertyName() + ", " + pvh.mKeyframes.getValue(0) + ", " +
pvh.mKeyframes.getValue(1));
}
}
super.start();
}
但是AnimationHandler.getInstance()是单例的,
public static AnimationHandler getInstance() {
if (sAnimatorHandler.get() == null) {
sAnimatorHandler.set(new AnimationHandler());
}
return sAnimatorHandler.get();
}
activity销毁时没有去remove掉监听器,监听器重的setAlpha方法又强关联 RelativeLayout,导致RelativeLayout无法释放资源,造成内存泄露,使用弱引用以后就可以解决这个问题。
或者在activity销毁的时候cancel这个动画也可以remove掉监听器,也能解决内存泄露。
更多推荐




所有评论(0)