Handler相关源码

构造一个带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



@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类似于
Map>
ThreadLocalMap是Thread一个属性,因为Thread t = Thread.currentThread();是线程安全的。ThreadLocal的的key值是AtomicInteger自增的int值。

每个线程有个Map,都有一个布袋,用于存放和当前线程有绑定关系的ThreadLocal。每个线程每个ThreadLocal只能存一份数据

为什么没有内存泄漏呢?保存ThreadLocal KV的Entry是个软引用,在Thread长与ThreadLocal场景下,也没有内存泄漏

Handler相关源码_第1张图片
屏幕快照 2018-01-25 下午1.51.12.png

如何让一个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

你可能感兴趣的:(Handler相关源码)