Android Native Looper机制

时间:2024-04-03 22:28:51

    Android Native Looper机制


在分析Native层代码的时候,很多地方都用到了Looper机制,本文将深入分析一下,方便理解相关机制,在Android系统中,Native层提供了类似于java层的消息循环机制。机制的核心是通过epoll机制,主要就是优化轮询操作,本文不做讲解。Native层的消息Looper机制代码,主要实现位于:

system/core/libutils/Looper.cpp

system/core/include/utils/Looper.h

说明


Looper机制包含两种实现方式,一种是通过sendMessage,另外一种是addFd。

sendMessage


提供如下三个方法:

Android Native Looper机制

addFd


Navite Looper 除了提供message机制之外,还提供了监听文件描述符的方式。

通过addFd()接口告之Looper,此文件描述符将要加入轮询之中。

Android Native Looper机制

其中:

-fd:为所需要轮询的文件描述符。

-ident:表示为当前发生事件的标识符,必须>=0,或者为POLL_CALLBACK(-2)如果指定了callback。

-events:表示为要监听的文件类型,默认是EVENT_INPUT。

-callback:当有事件发生时,会回调该callback函数。

-data:文件描述符fd里面的数据。


提供了两个addFd函数,一种是传入函数指针Looper_callbackFunc,回调的时候直接调用函数本身。还有一种是传入LooperCallback的子类。回调的时候执行handleMessage。

使用方法

addFd使用方法


使用方法,以inputdispatcher里面的代码举例说明,大致需要四步:

1、创建Looper。

Android Native Looper机制

2、启动Looper,并等待消息

Android Native Looper机制

3、增加fd到轮询池中

Android Native Looper机制


4、请求Looper进行poll操作

Android Native Looper机制


sendMessage使用方法

和addFd的区别仅仅存在于第三步。

1、创建Looper

2、启动looper并等待消息。

3、sendMessage,第一个参数的类必须继承了MessageHandler.

Android Native Looper机制

4、启动轮询。

原理分析

addFd原理分析

1、创建Looper的过程中,会创建一个mWakeEventFD,然后调用rebuildEpollLocked,重新更新当前被epoll实例监听轮询的fd,并将当前的mWakeEventFD和通过addFd添加的fd添加到创建的epoll实例中,也就是加入监控,当以上fd有处于可读或者可写状态时,则进行相应的操作。


Android Native Looper机制

Android Native Looper机制

2、接下来调用pollOnce,当系统有时间需要处理的时候,pollOnce的主要代码实现在pollInner。

Android Native Looper机制Android Native Looper机制

epoll_wait阻碍当前线程,当mEpollFd上监听的文件描述符有可读或者可写时间则继续执行。epoll机制是native looper的核心。针对Looper来说,当mWakeEventFD或者通过addFd添加的fd有可读可写事件,那么则继续往后执行,否则就阻塞在此处。默认情况会进行阻塞。

3、addFd,如果没有添加过当前fd,那么直接添加进epoll的监听之中,否则修改当前的epoll实例里面的fd。这样后续fd上有任何事件,就可以通过epoll_wait来进行控制了。到目前为止,epoll实例mEpollFd监听了mWakeEventFD和addFd添加的fd.

Android Native Looper机制

4、Looper调用wake,如下代码显示。Android Native Looper机制

mWakeEventFd就会有可读事件,那么epoll_wait就会继续往后执行。

Android Native Looper机制

epoll_wait会返回所有的事件eventsItems,如果是mWakeEventFd上的事件,那么执行awoken(),如果是通过addFd添加的fd上的事件,那么则通过pushResponse将当前的events添加到mReponse中。后续遍历回调的时候,会用到mResponses.

Android Native Looper机制

接下来就会执行callback函数了。

Android Native Looper机制

接下来会调用handleEvent。从而直接调用回调函数。

Android Native Looper机制

如上分析就完成了。


sendMessage原理分析

刚开始初始化的地方,和addFd一致,区别就是在sendMessage。主要有两个方法,一个是sendMessage,消息及时分发。还有一个sendMessageDelayed,延时分发消息。

Android Native Looper机制


Android Native Looper机制

都会将当前的消息添加到mMessageEnvelopes里面。消息池里面没有消息,那么i=0,就会调用wake(),唤醒epoll_wait,继续执行epoll_wait后面的内容,处理事件消息回调。如果还有延迟消息。正常的流程中,

3、接下来会调用pollOnce。

Android Native Looper机制

最终调用了handler的handleMessage.


总结

通过addFd方式添加的回调,如果参数是Looper_callbackFunc,那么最终调用function本身。如果参数是LooperCallback的子类,那么调用子类下覆写的handleEvent.如果是通过sendMessage方式来发送消息,那么最终调用的是实现了MessageHandler的子类的handleMessage方法。