Handler的实现原理
http://blog.csdn.net/blackzhangwei/article/details/51945516
Handler消息机制:
为了避免ANR,我们会通常把 耗时操作放在子线程里面去执行,当子线程需要更新的UI的时候就需要借助到安卓的消息机制,也就是Handler机制了。
handler机制是线程间通信机制,它可以在任意的线程之间通信。
一、创建Handler—-Handler handler = new Handler();
创建handler的两种形式:匿名内部类和内部类的形式。有人问:为什么要在主线程中创建Handler,而不在子线程中创建呢?
因为如果你在子线程创建Handler(如下),程序则会崩溃,并且会报错误:Can’t create handler inside thread that has not called Looper.prepare() ,翻译为:不能在没有调用Looper.prepare() 的线程中创建Handler。必须显示声明Looper。
扫描二维码关注公众号,回复:
185106 查看本文章
但是!为什么在主线程中创建Handler之前就不用调用Looper.prepare() 呢??
发现,Android程序的入口中,系统就默认帮我们调用了Looper.prepare()方法。
Android程序的入口在ActivityThread中的main()方法。
主线程中可以直接创建Handler,在子线程中需要先调用Looper.prepare()才能创建Handler。
二、发送消息—-mHandler.sendMessage(message);
小总结:发送消息的方法除了sendMessageAtFrontOfQueue(),例如sendMessage(),sendMessageDelayed()最终都会走sendMessageAtTime()方法。在sendMessageAtTime()方法中又调用MessageQueue的enqueueMessage()方法将所有的消息按时间来进行排序放在消息队列中。
三、处理消息—-Looper.loop()
通过轮询器的Looper.loop()方法中执行一个死循环把消息队列中的消息逐个取出来。死循环中主要通过MessageQueue的next()方法取出消息,取出消息后通过调用Handler的dispatchMessage()方法最终在handleCallback(msg)或者handleMessage(msg)方法处理消息。
HandlerThread的特点
- HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。
- 开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。
相比多次使用new Thread(){…}.start()这样的方式节省系统资源。
但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。 - HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。
- 通过设置优先级就可以同步工作顺序的执行,而又不影响UI的初始化;
总结
HandlerThread比较适用于单线程+异步队列的场景,比如IO读写操作,耗时不多而且也不会产生较大的阻塞。对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。