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