構(gòu)造一個(gè)帶Looper的子線程
final class DecodeThread extends Thread {
Handler getHandler() {
try {
handlerInitLatch.await();
} catch (InterruptedException ie) {
// continue?
}
return handler;
}
@Override
public void run() {
Looper.prepare();
handler = new DecodeHandler(activity, hints);
handlerInitLatch.countDown();//防止handler未初始化的場(chǎng)景
Looper.loop();
}}
停掉線程的方法 發(fā)送一個(gè) quit事件,自己主動(dòng)停掉
自定義id
<item name="quit" type="id" />
<item name="auto_focus" type="id" />
@Override
public void handleMessage(Message message) {
if (message.what == R.id.decode) {
decode((byte[]) message.obj, message.arg1, message.arg2);
} else if (message.what == R.id.quit) {
Looper.myLooper().quit();
}
}
事件驅(qū)動(dòng)也可以轉(zhuǎn)化為 運(yùn)行在線程池中的task驅(qū)動(dòng) 澡绩,缺點(diǎn)是 造成大量新類
Handler源碼
類圖依賴關(guān)系 sThreadLocal是個(gè)靜態(tài)變量持有Looper由缆,Looper持有Queue -》 持有Msg -》 持有Hanlder -》持有Activity
HandlerThread quit loop.prepare loop.loop
Binder Messenger
IdleHandler mIdleHandlers.toArray(mPendingIdleHandlers) 進(jìn)行了數(shù)據(jù)隔離施蜜,淺Copy斯够。返回false將會(huì)移除當(dāng)前idleHandler啸蜜。沒(méi)有when==0的msg時(shí)髓棋,在進(jìn)入阻塞前实檀,立即執(zhí)行IdleHandler。
MessageQueue是線程安全的阻塞隊(duì)列
a.線程安全保證是由 synchronized 保證的按声。
b.阻塞是由 nativePollOnce(ptr, nextPollTimeoutMillis); 保證的膳犹,相關(guān)標(biāo)志位為mBlocked
c.由when保證有序性
ThreadLocal有沒(méi)有內(nèi)存泄漏
Map<Thread,ThreadLocalMap>類似于
Map<Thread,Map<ThreadLocal,Value>>
ThreadLocalMap是Thread一個(gè)屬性,因?yàn)門hread t = Thread.currentThread();是線程安全的签则。ThreadLocal的的key值是AtomicInteger自增的int值须床。
每個(gè)線程有個(gè)Map,都有一個(gè)布袋渐裂,用于存放和當(dāng)前線程有綁定關(guān)系的ThreadLocal豺旬。每個(gè)線程每個(gè)ThreadLocal只能存一份數(shù)據(jù)
為什么沒(méi)有內(nèi)存泄漏呢?保存ThreadLocal KV的Entry是個(gè)軟引用柒凉,在Thread長(zhǎng)與ThreadLocal場(chǎng)景下哈垢,也沒(méi)有內(nèi)存泄漏
如何讓一個(gè)Thread具備loop功能?HandlerThread 是一個(gè)具有Looper的多生產(chǎn)單消費(fèi)的線程
如何停掉loop中的線程扛拨?looper.quit()
sThreadLocal 是如何保證線程安全的耘分?Thread.currentThread();是線程安全的
Thread.localValues持有ThreadLocal造成的內(nèi)存泄漏是怎么解決的? 存入的是 WeakReference绑警。
Queue.next()方法是阻塞的么求泰?是的,nativePollOnce保證
Queue是線程安全的么计盒?是的渴频,由synchronized保證
IdleHandler是個(gè)什么鬼,有何用北启? 在阻塞前執(zhí)行該回調(diào)卜朗,Queue阻塞代表著當(dāng)前無(wú)可執(zhí)行的Msg,無(wú)可執(zhí)行的Msg是只when==0的msg
ANR檢測(cè)
http://blog.csdn.net/itachi85/article/details/6918761
http://blog.csdn.net/half_bottle/article/details/78108424