use*_*746 4 android memory-leaks callback handler
handler1 是泄漏。
我想将handler1代码转换为handler2代码。这可以吗?
这两个代码有什么区别?
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// leaks!
Handler handler1 = new Handler()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("LOG", "Hello~1");
}
};
Handler handler2 = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e("LOG", "Hello~2");
return false;
}
});
handler1.postDelayed(new Runnable() {
@Override
public void run() { }
}, 60000);
handler2.postDelayed(new Runnable() {
@Override
public void run() { }
}, 60000);
finish();
}
}
Run Code Online (Sandbox Code Playgroud)
对于泄漏警告的原因,这篇文章解释得很好。
引自文章
在 Java 中,非静态内部类和匿名类持有对其外部类的隐式引用。另一方面,静态内部类则不然。
所以当你handler1通过匿名类创建时,它会持有对MainActivity实例的引用,MainActiviy不能被垃圾收集。
再次引用文章
要解决此问题,请在新文件中对 Handler 进行子类化,或者改用静态内部类。静态内部类不持有对其外部类的隐式引用,因此活动不会泄漏。如果您需要从处理程序内部调用外部活动的方法,请让处理程序持有对活动的 WeakReference,这样您就不会意外泄漏上下文。为了修复实例化匿名 Runnable 类时发生的内存泄漏,我们将变量设为类的静态字段(因为匿名类的静态实例不包含对其外部类的隐式引用):
按照文章,更新您的代码如下:
public class MainActivity extends AppCompatActivity {
private static class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("LOG", "Hello~1");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler handler1 = new MyHandler();
handler1.postDelayed(new Runnable() {
@Override
public void run() { }
}, 60000);
finish();
}
}
Run Code Online (Sandbox Code Playgroud)
@Michael这个 Handler 类的答案应该是静态的,否则可能会发生泄漏:IncomingHandler 提供了解决方案。
引用@Michael的回答
据我了解,这不会避免潜在的内存泄漏。消息对象持有对 mIncomingHandler 对象的引用,该对象持有对 Handler.Callback 对象的引用,该对象持有对服务对象的引用。只要 Looper 消息队列中有消息,Service 就不会被 GC。但是,除非消息队列中有长时间延迟的消息,否则这不会是一个严重的问题。
在您的情况下,handler2将持有对对象的引用。Handler.Callback由于Handler.Callback是由匿名类创建的,因此它也将持有对MainActiviy实例的引用。所以MainActiviy实例也不能被垃圾收集。
| 归档时间: |
|
| 查看次数: |
2338 次 |
| 最近记录: |