Android的消息机制主要指的是handler的运行机制.Handler是消息机制的上层接口,开发过程中需要和Handler交互即可,我们大部分时候通常利用Handler做更新UI的操作,比如在子线程中有一些I/O,读取文件或者网络请求一些耗时的操作,在这之后需要我们更新UI,但是我们知道Android开发中是不允许子线程访问UI控件的,这时候就利用Handler来处理UI上的操作了.Handler的底层实现是通过MessageQueue和Looper来支撑的,MessageQueue是消息队列,以队列的形式对外提供插入和删除的操作,这里需要提一下的是,MessageQueue的内部存储结构并不是队列,而是单链表的数据结构来存储消息列表.Looper是一个消息的循环体,无限循环去处理新消息,有则处理,没有则一直等待.Looper中还有个东西,叫做ThreadLocal,它不是线程,他可以在每一个线程中存储数据.Handler内部通过ThreadLocal来获取当前线程中的Looper,它可以在不同的线程中互不干扰的存储并提供数据,通过它可以轻松的获取每个线程的Looper.我们在使用Handler的时候都会先创建一个Looper对象,因为线程默认是没有Looper的,但是在主线程(UI线程)中,当UI线程被创建时就已经初始化了Looper,所以我们在主线程中可以直接使用Handler.
如果访问UI控件,那肯定会涉及到ViewRootImpl这个类,下面的源码中方法就是来检测是否当前线程是否是主线程.如果是非UI线程则会报下面的错误.
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}}
那么再来说说子线程为什么不能更新UI.Android的UI控件不是线程安全的,如果多线程并发访问UI控件,那么可能会导致UI控件处于不可预期的状态.那么为什么系统不对UI控件的访问加上锁机制呢?因为加上锁机制会让访问UI的逻辑变的复杂,再就是锁机制会降低UI访问的效率,因为锁机制会阻塞某些线程的执行.