Handler 是Android的消息机制的上层接口,这使得在开发过程中只需要和Handler交互即可,通过它可以很轻松地将一个任务切换到 Handler 所在的线程中去执行。
Android 的消息机制主要是指 Handler 的运行机制,handler的运行需要底层的 MessageQeue 和 Looper 的支撑。
MessageQueue 内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息列表。
Looper 会以一种无限循环的形式去查是否有新消息,如果有的话就处理消息,否则就一直等待着。 looper 还有一个特俗的概念就是 ThreadLocal ,
ThreaedLocal 并不是线程,它的作用就是可以在每个线程中存储数据。Handler 创建的时候采用当前线程的 Looper 来构造消息循环系统,那么 Hnalder 内部是如何来获取到当前 Looper 的呢
线程默认没有 Looper ,如果需要使用 Handler 就必须为线程创建 Looper ,我们经常提到的主线程也就是UI线程, ActivityThread ,在创建时就会初始化Looper , 这也是主线程中默认 可以使用 Handler的原因
Handler主要功能是将一个任务切换到某个指定线程中,为什么需要这个功能呢
这是因为 Android 规定访问 UI 只能在主线程中进行,如果子线程访问UI 会抛出异常
系统为什么不允许子线程中访问UI呢?
这是因为 Android 的 UI 控件不是线程安全的,如果在多线程中并发访问可能会导致UI 控件处于不可预期的状态
为什么系统不对UI控件的访问加上锁机制呢?
缺点有两个:
- 首先加上锁机制会让UI访问的机制变得复杂
- 其次所机制会让UI访问的效率
Handler 创建时会采用当前线程的 Looper 来构建内部的消息循环系统,如果当前线程没有 Looper ,那么就会报错
Handler的本质是更新UI?
这的确没错,但是更细nUI仅仅是Handler的一个特殊使用场景。具体来说:又是以后需要在子线程中进行耗时的I/O操作,可能是读取文件或者访问网络等,我们不能在子线程中访问UI控件,否则就会出发程序异常,这个时候通过Handler就可以将更新UI的操作切换到主线程中执行。