Looper源码

以下是 Android Native 层 Looper 的核心实现(选自 AOSP frameworks/native/libs/utils/Looper.cpp):

namespace android {

static const int EPOLL_SIZE_HINT = 8;
static const int EPOLL_MAX_EVENTS = 16;

Looper::Looper(bool allowNonCallbacks)
    : mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
      mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
    int wakeFds[2];
    pipe(wakeFds);
    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];
    fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
    fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
    mEpollFd = epoll_create(EPOLL_SIZE_HINT);

    epoll_event eventItem;
    eventItem.events = EPOLLIN;
    eventItem.data.fd = mWakeReadPipeFd;
    epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
}

Looper::~Looper() {
    close(mWakeReadPipeFd);
    close(mWakeWritePipeFd);
    close(mEpollFd);
}

// thread-local support
void Looper::initTLSKey() { pthread_key_create(...); }
sp<Looper> Looper::getForThread() { pthread_getspecific(...); }
sp<Looper> Looper::prepare(int opts) {
    sp<Looper> looper = getForThread();
    if (!looper) {
        looper = new Looper(opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
        setForThread(looper);
    }
    return looper;
}

// 添加文件描述符监听
int Looper::addFd(int fd, int ident, int events,
                  const sp<LooperCallback>& callback, void* data) {
    // 构造 Request 并 epoll_ctl 注册 fd...
}

// 等待事件,最多返回一条
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    while (mResponseIndex < mResponses.size()) {
        // 从缓存的响应队列中调度已有事件
    }
    return pollInner(timeoutMillis);
}

上述仅展示了 Looper 的部分核心内容,完整代码包括以下几个模块:

  1. 唤醒管道(wake pipe):用于外部线程唤醒 Looper。
  2. epoll_create + epoll_ctl:用于把唤醒管道加入事件监听。
  3. 文件描述符注册/删除:通过 addFd / removeFd 管理监听。
  4. 事件轮询:pollOnce()与 pollInner() 实现基于 epoll 的阻塞与事件分发机制。
  5. 线程本地存储:每个线程最多一个 Looper(prepare() + TLS)。
  6. Callback 调用:监听到 fd 可读/可写等事件时,会调度 LooperCallback::handleEvent()。

参考信息

  • Looper 基于 Linux epoll() 实现,只为方便理解,示例中省略了部分错误检查和消息队列相关逻辑。
  • 上述代码摘自 AOSP Looper.cpp,稍作删减以保留关键部分  。

如果你想要查看完整实现以及 addFd、pollInner、removeFd 具体逻辑,可以通过以下路径访问:

frameworks/native/libs/utils/Looper.cpp

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器