构造一个带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未初始化的场景
Looper.loop();
}}
停掉线程的方法 发送一个 quit事件,自己主动停掉
自定义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();
}
}
事件驱动也可以转化为 运行在线程池中的task驱动 ,缺点是 造成大量新类
Handler源码
类图依赖关系 sThreadLocal是个静态变量持有Looper,Looper持有Queue -》 持有Msg -》 持有Hanlder -》持有Activity
HandlerThread quit loop.prepare loop.loop
Binder Messenger
IdleHandler mIdleHandlers.toArray(mPendingIdleHandlers) 进行了数据隔离,浅Copy。返回false将会移除当前idleHandler。没有when==0的msg时,在进入阻塞前,立即执行IdleHandler。
MessageQueue是线程安全的阻塞队列
a.线程安全保证是由 synchronized 保证的。
b.阻塞是由 nativePollOnce(ptr, nextPollTimeoutMillis); 保证的,相关标志位为mBlocked
c.由when保证有序性
ThreadLocal有没有内存泄漏
Map<Thread,ThreadLocalMap>类似于
Map<Thread,Map<ThreadLocal,Value>>
ThreadLocalMap是Thread一个属性,因为Thread t = Thread.currentThread();是线程安全的。ThreadLocal的的key值是AtomicInteger自增的int值。
每个线程有个Map,都有一个布袋,用于存放和当前线程有绑定关系的ThreadLocal。每个线程每个ThreadLocal只能存一份数据
为什么没有内存泄漏呢?保存ThreadLocal KV的Entry是个软引用,在Thread长与ThreadLocal场景下,也没有内存泄漏
如何让一个Thread具备loop功能?HandlerThread 是一个具有Looper的多生产单消费的线程
如何停掉loop中的线程?looper.quit()
sThreadLocal 是如何保证线程安全的?Thread.currentThread();是线程安全的
Thread.localValues持有ThreadLocal造成的内存泄漏是怎么解决的? 存入的是 WeakReference。
Queue.next()方法是阻塞的么?是的,nativePollOnce保证
Queue是线程安全的么?是的,由synchronized保证
IdleHandler是个什么鬼,有何用? 在阻塞前执行该回调,Queue阻塞代表着当前无可执行的Msg,无可执行的Msg是只when==0的msg
ANR检测
http://blog.csdn.net/itachi85/article/details/6918761
http://blog.csdn.net/half_bottle/article/details/78108424