Android Looper类代码分析

本文详细剖析了Android中Looper类的工作原理,包括其对epoll系统调用的使用,事件处理接口,回调函数,以及如何添加和处理文件描述符事件。通过分析Looper的源码,展示了其内部的消息处理流程和事件响应机制。
摘要由CSDN通过智能技术生成

本文将分析一下Looper类的实现及其应用,代码位于

frameworks/native/lib/utils/Looper.cpp。主要分为如下几个部分:

1. epoll系统调用接口简介

2. Looper类代码分析

3. Looper类应用实例分析


一、epoll系统调用接口简介

Looper事件机制实际上是依赖系统调用epoll实现的。它是一种I/O复用模型,即可以同时监控多个I/O事件。对于Looper来说,所谓的I/O事件就是所监控的文件描述符上没有有数据到达。epoll的主要接口如下所示 :

1. epoll_create():创建一个epoll实例,返回引用该实例的文件描述符。

原型如下所示 :

 

int epoll_create(int size );

 

参数size指定了我们想通过epoll实例监控文件描述符的数量。

 

2. epoll_ctl():操作与该epoll实例相关联的兴趣列表:添加一个文件描述符到兴趣列表中,从兴趣列表中删除一个现存的文件描述符以及修改事件掩码以决定要监控文件描述符上发生的哪个事件。

原型如下所示:

 

int epoll_ctl(int epfd , int op , int fd , struct epoll_event * ev );

 

其中参数op可以取如下一些值:

 

EPOLL_CTL_ADD

fd加入了监控列表

EPOLL_CTL_MOD

修改当前监控的fd相关信息

EPOLL_CTL_DEL

fd从监控列表中删除

 

 

3. epoll_wait():从I/O Ready列表中返回与epoll实例相关联的项,即返回有事件发生的文件描述符的数量。

      原型如下所示:

 

int epoll_wait(int epfd , struct epoll_event * evlist , int maxevents , int timeout );

 

其中timeout值为-1时,表示无限等待直到有事件发生。为0时,执行一个非阻塞检查后立即返回。大于0时,表示一个超时时间值。

另外,struct epoll_event结构定义如下所示 :

struct epoll_event {
    uint32_t events;  /* epoll events (bit mask) */
    epoll_data_t data; /* User data */
};

主要的事件掩码有:

EPOLLIN:代表有数据可读

EPOLLOUT:代表有数据可写

 

epoll_data_t的数据结构定义如下:

typedef union epoll_data {
    void *ptr;  /* Pointer to user-defined data */
    int fd;  /*File descriptor */
    uint32_t u32; /* 32-bit integer */
    uint64_t u64; /* 64-bit integer */
} epoll_data_t;

使用实例:

int epfd;
struct epoll_event ev;
epfd = epoll_create(5);
if (epfd == -1)
    errExit("epoll_create");
ev.data.fd = fd;
ev.events = EPOLLIN;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, ev) == -1)
    errExit("epoll_ctl");
...
epoll_wait(...);

二、Looper类代码分析

Looper类定义了一种事件接口,这里所谓的事件就是文件描述符上的I/O数据是否可读或可写。它提供了一系列接口来支持事件通知和响应,通过轮询,利用epoll系统调用,可以侦测到发生在文件描述符上的I/O事件。

在分析Looper类之前,我们先来看两个与之相关的接口:

1. Looper消息处理接口。

class MessageHandler : public virtual RefBase {
protected:
    virtual ~MessageHandler() { }

public:
    /**
     * Handles a message.
     */
    virtual void handleMessage(const Message& message) = 0;
};

与之相关的Looper类的几个成员函数定义如下:

/**
     * Enqueues a message to be processed by the specified handler.
     */
    void sendMessage(const sp<MessageHandler>& handler, const Message& message);

    /**
     * Enqueues a message to be processed by the specified handler after all pending messages
     * after the specified delay.
     */
    void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
            const Message& message);

    /**
     * Enqueues a message to be processed by the specified handler after all pending messages
     * at the specified time.
     */
    void sendMessageAtTime(n
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值