说到handler机制的话 涉及到4个类:Handler、Message、MessageQueue、Looper
我们通常用的都是子线程向主线程发送消息,大致的流程是 子线程发送MSG到MessageQueue队列涉及到的方法依次是:handler.sendMessage()->handler.equeueMessage()->messageQueue.enqueueMessage()
主线程取消息处理消息的流程是:ActivityThread.main()->Looper.loop()->MessageQueue.next()->
handler.dispatchMessage()->handler.handleMessage();
其实handler实现线程切换的实质是线程间内存共享 也就是MessageQueue共享
这里还有一个handler内存泄漏的问题 其实质不是因为匿名内部类的原因 而是因为 handler是被looper(GCRoot)间接引用的对象具体的引用是:
Looper(static)->MessageQueue->Message(有可能不会释放)->handler->activity
这个持有链不会断开的时候 activity就泄漏了 两种方法可以避免 一个是用 static+弱引用 这样handler就不会持有activity的引用 还有一个是activity关闭的时候 移除所有消息 切断message处的持有链
发消息的时候为什么不用new Message()而是用message.obtin() 这样是为了避免频繁GC
造成STW(stop the world 因为gc时所有线程都将停止),从而造成画面卡顿
还有一个原因就是new 空间会产生内存碎片导致连续内存不够 最后造成oom
ThreadLocal类 主要作用是线程间隔离 这里面还涉及到一个epoll机制 这个epoll是阻塞可扩展io处理机制