一直在用Handler,但卻一直因?yàn)椴荒軠?zhǔn)確表述其工作原理而耿耿于懷,現(xiàn)在正好有時(shí)間介衔,自己決定初步梳理下恨胚。如果有整理不足或不準(zhǔn)確的地方,請(qǐng)大家批評(píng)指正炎咖。
相信大家對(duì)于主線程中創(chuàng)建并使用Handler一點(diǎn)都不陌生了赃泡。如下圖所示:(聲明為static的靜態(tài)類原因是避免Handler作為內(nèi)部類寒波,避免隱式持有外部引用導(dǎo)致的內(nèi)存泄漏問(wèn)題。)
或許大家也有碰到過(guò)類似于下面的聲明方法:
Handler mainHandler = newHandler(Looper.getMainLooper());
但是閱讀Handler源碼發(fā)現(xiàn)升熊,Handler提供了多種構(gòu)造方法以供使用:
1俄烁、public Handler() ?{ this(null,false); }
2、public Handler(Callback callback) ?{ this(callback,false); }
3级野、public Handler(Looper looper) { this(looper,null,false); }
4页屠、public Handler(Looper looper, Callback callback) { this(looper, callback,false);}
5、public Handler(boolean async) {this(null, async);}
6蓖柔、public Handler(Callback callback, boolean async) {}
7卷中、public Handler(Looper looper, Callback callback,booleanasync) {}
可以看到,如果未傳入最常見(jiàn)的參數(shù)為空的構(gòu)造方法其實(shí)引用的序號(hào)為6的構(gòu)造方法渊抽。其實(shí)大家應(yīng)該也有發(fā)現(xiàn):Handler如果不顯式傳入Looper 創(chuàng)建對(duì)象的話蟆豫,最后都會(huì)調(diào)用序號(hào)為6的構(gòu)造方法,而如果顯示傳入Looper的話懒闷,最后都會(huì)調(diào)用序號(hào)為7的構(gòu)造方法十减。
而構(gòu)造方法6與構(gòu)造方法7的區(qū)別是什么呢?附上源碼大家應(yīng)該就比較清楚了
可以看到愤估,唯一的區(qū)別或許就是mLooper的獲取方式了帮辟,而在構(gòu)造方法6中, 如果mLooper對(duì)象為空的時(shí)候玩焰,會(huì)拋出一個(gè)異常由驹,稱在線程中創(chuàng)建handler時(shí)沒(méi)用調(diào)用Looper.prepare()方法。我想這也許就是大多數(shù)時(shí)候在子線程中調(diào)用構(gòu)造方法1昔园,時(shí)會(huì)拋出異常的原因了蔓榄。
至于為何會(huì)拋出異常,請(qǐng)期待對(duì)Looper類的分析吧~~~??
ps:或許有哪位小伙伴能回答下FIND_POTENTIAL_LEAKS這個(gè)參數(shù)有什么意義呢默刚?
更新后續(xù)相關(guān)文章的傳送門(mén):