【安卓】Android 自定义控件 这样子写Handler正确吗?

在写自定义控件时,IDE提示这样子写可能会发生泄漏

【安卓】Android 自定义控件 这样子写Handler正确吗?

提示可能发生泄漏的代码

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检测后并没有发现什么,但是我不知道这样子写是否规范?

回答

可以这样写,但是建议在View被销毁的时候比如onDetachedFromWindow回调方法将发的delay的消息移除掉

你是想要写一个匿名内部类。因为非静态的内部类为在Java编译成字节码后也是一个独立的类,但是为了达到内部类访问外部类中的成员变量和方法的功能,字节码中会持有外部类的一个对象的引用,才可以在两个独立类里面互相访问。如果你发送延迟Message的时候,Message 的成员变量target会持有Handler的引用,而这个匿名内部类Handler的对象又持有View的对象的引用。所以造成了该View对象不能及时被回收掉

如果改成静态的匿名内部类,该类只能访问外部类的静态方法和静态变量,所以不会持有外部类的实例对象。

以上是 【安卓】Android 自定义控件 这样子写Handler正确吗? 的全部内容, 来源链接: utcz.com/a/99131.html

回到顶部