Android Handler原理

1、看看handler的构造方法:


image.png

在构造方法里获取了mLooper 和一个mQueue,可以明确看出如果looper为空的话就会抛一个runtime异常,让我们先去调用Looper.prepare()方法
然后看看Looper.myLooper做了什么事:


image.png

这是looper.myLooper的实现就是以currentThread为键,去ThreadLocalMap里找到相应的looper。
再看看looper.prepare做了什么:
image.png

image.png

prepare方法就是将当前looper和当前线程放入threadLocal中去。
在这里思考一个问题:
是否可以在主线程中new一个looper?
获取looper的方式就是looper.prepare,在主线程中调用会抛异常new RuntimeException("Only one Looper may be created per thread");

2、当调用handler.sendMessage时:


image.png

会调用enqueueMessage这个方法将message的target 和uid指定为当前handle 并且加入队列。

再然后调用Looper.loop方法,,开启无线循环模式,去不断获取messageQueue中的message并且调用message.target.dispatchMessage方法去处理message。
这个时候就涉及另外一个问题:
Looper的死循环为何不会卡死。这里就涉及到了linux的epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里。

此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个[描述符]当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。

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