Handler的实现原理

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并不适合,因为它只有一个线程,还得排队一个一个等着。






猜你喜欢

转载自blog.csdn.net/wg_1176075838/article/details/79549731