好记性不如烂笔头。生活中多做笔记,不仅可以方便自己,还可以方便他人。
前段时间,同事跟我说他遇到一个很奇怪的问题:退出页面,Activity销毁时onStop或onDestroy延时10s左右才回调。如图:
听到这个问题,首先想到的是因为在SecondActivity的onPause或在MainActivity的onResume里执行了什么耗时操作导致的。后来检查了一遍发现没有做耗时操作。找了很久没找到原因,于是决定用最笨的排除法,删减不必要的代码。后面发现是前一个activity的动画一直没有停止,额,这。。。。。。。好吧,不去追究是谁写的,反正这样写肯定是不对的。页面不可见,一定要停止动画,这是要养成的习惯。
好,那我们就在onPause时停止动画,在onResume时恢复动画,类似这样:
@Override
protected void onPause() {
super.onPause();
Log.d("test", "MainActivity, onPause");
valueAnimator.cancel();
}
@Override
protected void onResume() {
super.onResume();
Log.d("test", "MainActivity, onResume");
valueAnimator.start();
}
原以为这样就可以大功告成了,但是修改后,发现问题依然存在。后面同事去检查动画代码才发现是动画的问题
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// .....
view.postInvalidate();
// .....
}
});
view.postInvalidate()?是的,没看错,是使用了view的postInvalidate方法来进行UI刷新重绘导致的。把它修改成invalidate()方法试试:
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// .....
view.invalidate();
// .....
}
});
修改后,activity的销毁就正常了。
那问题的原因是什么呢?虽然我没有具体去证实,但我猜是因为postInvalidate()内部是采用了handler来实现的,而正巧,activity的onStop和onDestroy回调也是采用handler来实现的。在onResume时恢复动画,post了大量的MSG_INVALIDATE到main handler的MessageQueue中,导致onStop和onDestroy得不到及时的回调。
但还有一个问题还没有想明白,为什么都是固定大概延时10s左右呢?
这里先把问题记录起来,等我有空了再去深入研究。