一直在用Handler,但卻一直因為不能準確表述其工作原理而耿耿于懷,現在正好有時間,自己決定初步梳理下。如果有整理不足或不準確的地方,請大家批評指正。
相信大家對于主線程中創建并使用Handler一點都不陌生了。如下圖所示:(聲明為static的靜態類原因是避免Handler作為內部類,避免隱式持有外部引用導致的內存泄漏問題。)
或許大家也有碰到過類似于下面的聲明方法:
Handler mainHandler = newHandler(Looper.getMainLooper());
但是閱讀Handler源碼發現,Handler提供了多種構造方法以供使用:
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) {}
可以看到,如果未傳入最常見的參數為空的構造方法其實引用的序號為6的構造方法。其實大家應該也有發現:Handler如果不顯式傳入Looper 創建對象的話,最后都會調用序號為6的構造方法,而如果顯示傳入Looper的話,最后都會調用序號為7的構造方法。
而構造方法6與構造方法7的區別是什么呢?附上源碼大家應該就比較清楚了
可以看到,唯一的區別或許就是mLooper的獲取方式了,而在構造方法6中, 如果mLooper對象為空的時候,會拋出一個異常,稱在線程中創建handler時沒用調用Looper.prepare()方法。我想這也許就是大多數時候在子線程中調用構造方法1,時會拋出異常的原因了。
至于為何會拋出異常,請期待對Looper類的分析吧~~~??
ps:或許有哪位小伙伴能回答下FIND_POTENTIAL_LEAKS這個參數有什么意義呢?
更新后續相關文章的傳送門: