while (true) {
MyMessage msg = queue.take(); // might block
System.out.println("Received: " + msg);
}
msg對象是棧上的局部變量,每次循環(huán)都將會重寫,一旦被重寫,上一次循環(huán)的msg引用指向的對象將不再被其引用;但是在Dalvik虛擬機(jī)的實現(xiàn)中,如果queue.take()阻塞了,那么本次循環(huán)的msg未被賦值,則上次的msg的引用將不會被清除,
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
return;
}
msg.target.dispatchMessage(msg);
msg.recycleUnchecked();
}
msg每次循環(huán)的后面都被recycle了(清空了內(nèi)容),所以泄漏的僅僅是一個空的msg對象,影響不大(LeakCanary將默認(rèn)忽略Message對象的泄漏)。
new AlertDialog.Builder(this)
.setPositiveButton("Baguette", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
MyActivity.this.makeBread();
}
})
.show();
DialogInterface.OnClickListener的匿名實現(xiàn)類持有了MainActivity的強(qiáng)引用;而在AlertDialog的實現(xiàn)中,OnClickListener類將被包裝在一個Message對象中,而且這個Message會在其內(nèi)部被復(fù)制一份,兩份Message中只有一個被recycle,另一個(OnClickListener的成員變量引用的Message對象)將會leak!
DialogInterface.OnClickListener
對象不持有外部類的強(qiáng)引用:static類實現(xiàn);DetachableClickListener(監(jiān)聽窗口解除事件,手動釋放引用);