当前位置:   article > 正文

java 匿名类 内存泄露_Android - 匿名内部类导致内存泄露的处理办法

匿名listener会有内存泄露吗?

在使用各种 listener 时,稍有不注意就会导致内存泄露,因此在使用延时返回的回调时,需要格外小心。

demo

先看一个的 demo:MainActivity 点击按钮后,调用 LongTimeOperation 开启一个耗时 10 秒的线程,并在执行完成后调用回调 onLongTimeCallback()。

MainActivity 中开启耗时操作的代码:

private void startLongTimeOperation() {

LongTimeOperation longTimeOperation = new LongTimeOperation();

LongTimeOperation.LongTimeCallback longTimeCallback = new LongTimeOperation.LongTimeCallback() {

@Override

public void onLongTimeCallback() {

text.setText("onLongTimeCallback");

}

};

longTimeOperation.setLongTimeCallback(longTimeCallback);

longTimeOperation.start();

}

LongTimeOperation 中耗时操作的代码:

public void start() {

new Thread(() -> {

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

e.printStackTrace();

}

mMainHandler.post(() -> {

if (longTimeCallback != null) {

longTimeCallback.onLongTimeCallback();

}

});

}).start();

}

在以上的代码中,由于 longTimeCallback 是匿名内部类,持有了外部的引用,在这个例子里持有了 MainActivity 的引用。

Anonymous-Inner-Class-Leaks_Memory_1.png

因此,在 MainActivity onDestory() 后,由于 longTimeOperation 持有 longTimeCallback 的引用,而 longTimeCallback 持有了 MainActivity 的引用,导致 GC 的时候无法回收 MainActivity 实例,造成了内存泄露。

Anonymous-Inner-Class-Leaks_Memory_2.png

改进方案一:将回调中所有对象放入 WeakReference 中

为了避免匿名内部类引用 Activity 的问题,可以把回调里的操作单独提出来,在这个例子中就是回调中需要用到的 TextView。

改动过后,longTimeOperation 引用的是 weakLongTimeCallback,weakLongTimeCallback 中的 TextView 是在 WeakReference 中。因此当 MainActivity 被回收时,textView 也能被回收,避免了内存泄露。

Anonymous-Inner-Class-Leaks_Memory_3.png

private void startLongTimeOperation() {

L

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/683254
推荐阅读
相关标签
  

闽ICP备14008679号