Handler原理

1.Handler是用来将任务切换到Handler所在的线程的,并不只是更新UI,只是常被用来更新UIAndroid UI线程是不安全的,如果多个线程更新UI可能造成不可预料的后果,所以Android规定不能在非UI线程中更新UI,在进行UI操作的时候ViewRootImpl会去检查当前线程是否是UI线程,不是就抛异常,故此我们常用Handler来切换线程。

2.MessageQueue内部存储结构其实是单链表,负责存储消息。

3.Looper会无限循环地去查找MessageQueue是否有新消息,有就处理,否则就阻塞等待。Handler创建时会采用当前的Looper来构建消息循环,如果没有Looper就抛异常,所以Handler创建之前先初始化Looper(调用Looper.prepare()方法)或在有Looper的线程中创建。UI线程之所以不用初始化Looper,是因为在Activity初始化的时候就新建了一个Looper,属于后者。

4.ThreadLocal可以在不同线程中互不干扰地存储并提取数据,也就是说,相当于每个线程都分配了一个本地的数据块用来存放或提取本线程的数据。在Handler中主要用来在线程中存取Looper

5.Handler处理消息原理:
(1)Looper.prepare()初始化Looper,这里初始化内部的MessageQueue,并把当前线程对象存起来;
(2)创建Handler,这里获取当前线程的Looper对象,并获取LooperMessageQueue,获取不到Looper就抛异常;
(3)Looper.loop()开启无限循环,在循环里面会去调用MessageQueuenext方法获取消息对象,只要消息对象不为空就分发出去(调用Looperquit方法会改变MessageQueuemQuitting标志,next方法会返回null),否则跳出循环,next里面也是个无限循环,查询消息队列里面是否有待处理的消息(每个Message对象都有个时间标志,到点了就是可以处理),有就取出消息并移除这个消息,没有就阻塞等待;
(4)Handler调用post(最终都调用send方法)或send方法发送消息,最后都是调用sendMessageAtTime方法,方法里面调用(5);
(5)MessageQueue调用enqueueMessage方法将消息放入消息队列,这里是按照消息的时间顺序插入的,最新的在最前面;
(6)在(3)中的循环中Looper检查到有新消息(最新的消息),调用HandlerdispatchMessage方法,进一步调用RunnableHandlerhandMessage方法;。
(7)Looper是运行在Handler创建的线程中,因此Looper在处理过程中就将线程切换到Handler所在线程了。

你可能感兴趣的:(Handler原理)