Android 自定义控件 这样子写Handler正确吗?
在写自定义控件时,IDE提示这样子写可能会发生泄漏
提示可能发生泄漏的代码
private class CustomHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (animCurrentPage < animMaxPage && animCurrentPage >= 0) {
invalidate();
if (animState == ANIM_NULL) {
return;
}
if (animState == ANIM_CHECK) {
animCurrentPage++;
} else if (animState == ANIM_UNCHECK) {
animCurrentPage--;
}
this.sendEmptyMessageDelayed(0, animDuration / animMaxPage);
Log.e("CustomHandler", "animCurrentPage:" + animCurrentPage);
} else {
if (isCheck) {
animCurrentPage = animMaxPage - 1;
} else {
animCurrentPage = -1;
}
invalidate();
animState = ANIM_NULL;
}
}
}
通过搜索引擎搜索到结果后,修改后的代码
private static class CustomHandler extends Handler {
private final WeakReference<CheckView> mCheckView;
CustomHandler(CheckView checkView) {
mCheckView = new WeakReference<>(checkView);
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
CheckView checkView = mCheckView.get();
if (checkView != null) {
int animCurrentPage = checkView.animCurrentPage;
int animMaxPage = checkView.animMaxPage;
int animState = checkView.animState;
if (animCurrentPage < animMaxPage && animCurrentPage >= 0) {
checkView.invalidate();
if (animState == ANIM_NULL) {
return;
}
if (animState == ANIM_CHECK) {
checkView.animCurrentPage++;
} else if (animState == ANIM_UNCHECK) {
checkView.animCurrentPage--;
}
this.sendEmptyMessageDelayed(0, checkView.animDuration / animMaxPage);
Log.e("CustomHandler", "animCurrentPage:" + animCurrentPage);
} else {
if (checkView.isCheck) {
checkView.animCurrentPage = animMaxPage - 1;
} else {
checkView.animCurrentPage = -1;
}
checkView.invalidate();
checkView.animState = ANIM_NULL;
}
}
}
}
请问一下,这样子修改后,是否就可以解决泄漏的问题呢?我通过LeakCanary检测后并没有发现什么,但是我不知道这样子写是否规范?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可以这样写,但是建议在View被销毁的时候比如
onDetachedFromWindow
回调方法将发的delay的消息移除掉你是想要写一个匿名内部类。因为非静态的内部类为在Java编译成字节码后也是一个独立的类,但是为了达到内部类访问外部类中的成员变量和方法的功能,字节码中会持有外部类的一个对象的引用,才可以在两个独立类里面互相访问。如果你发送延迟Message的时候,Message 的成员变量target会持有Handler的引用,而这个匿名内部类Handler的对象又持有View的对象的引用。所以造成了该View对象不能及时被回收掉
如果改成静态的匿名内部类,该类只能访问外部类的静态方法和静态变量,所以不会持有外部类的实例对象。