Looper

摘要

枚举

匿名枚举 48{
  ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1<<0
}
enum
ALooper_prepare() 的选项。
匿名枚举 49{
  ALOOPER_POLL_WAKE = -1,
  ALOOPER_POLL_CALLBACK = -2,
  ALOOPER_POLL_TIMEOUT = -3,
  ALOOPER_POLL_ERROR = -4
}
enum
匿名枚举 50{
  ALOOPER_EVENT_INPUT = 1 << 0,
  ALOOPER_EVENT_OUTPUT = 1 << 1,
  ALOOPER_EVENT_ERROR = 1 << 2,
  ALOOPER_EVENT_HANGUP = 1 << 3,
  ALOOPER_EVENT_INVALID = 1 << 4
}
enum
looper 可以监控的文件描述符事件标志。

类型定义

ALooper typedef
struct ALooper
ALooper。
ALooper_callbackFunc)(int fd, int events, void *data) typedef
int(*
对于基于回调的事件循环,这是文件描述符事件发生时调用的函数原型。

变量

信息
int ALooper_pollAll 可能会忽略唤醒。请改用 ALooper_pollOnce。有关更多信息,请参阅 API 文档。

函数

ALooper_acquire(ALooper *looper)
void
获取给定 ALooper 对象的引用。
ALooper_addFd(ALooper *looper, int fd, int ident, int events, ALooper_callbackFunc callback, void *data)
int
向 looper 添加一个新的文件描述符以便进行轮询。
ALooper_forThread()
返回与调用线程关联的 looper,如果没有则返回 NULL。
ALooper_pollAll(int timeoutMillis, int *outFd, int *outEvents, void **outData) __REMOVED_IN(1
int
已弃用。 应将对 ALooper_pollAll() 的调用替换为 ALooper_pollOnce()。如果您在循环中调用 ALooper_pollOnce(),则必须将所有返回值视为也表示 ALOOPER_POLL_WAKE。
类似于 ALooper_pollOnce(),但会执行所有待处理的回调,直到所有数据已被消费或某个文件描述符可用但没有回调。
ALooper_pollOnce(int timeoutMillis, int *outFd, int *outEvents, void **outData)
int
等待事件可用,可以选择设置超时时间(以毫秒为单位)。
ALooper_prepare(int opts)
准备与调用线程关联的 looper,并返回它。
ALooper_release(ALooper *looper)
void
删除先前使用 ALooper_acquire() 获取的引用。
ALooper_removeFd(ALooper *looper, int fd)
int
从 looper 中移除先前添加的文件描述符。
ALooper_wake(ALooper *looper)
void
异步唤醒轮询。

枚举

匿名枚举 48

android/looper.h 中声明
 Anonymous Enum 48

ALooper_prepare() 的选项。

属性
ALOOPER_PREPARE_ALLOW_NON_CALLBACKS

此 looper 将接受没有回调函数(即为回调提供 NULL)的 ALooper_addFd() 调用。

在此情况下,调用 ALooper_pollOnce()ALooper_pollAll() 的代码必须检查这些函数的返回值,以发现此类文件描述符上何时有数据可用并进行处理。

匿名枚举 49

android/looper.h 中声明
 Anonymous Enum 49

ALooper_pollOnce()ALooper_pollAll() 的结果。

属性
ALOOPER_POLL_CALLBACK

ALooper_pollOnce() 的结果:执行了一个或多个回调。

轮询也可能已由 ALooper_wake() 显式唤醒。

ALOOPER_POLL_ERROR

ALooper_pollOnce()ALooper_pollAll() 的结果:发生了错误。

轮询也可能已由 ALooper_wake() 显式唤醒。

ALOOPER_POLL_TIMEOUT

ALooper_pollOnce()ALooper_pollAll() 的结果:超时已过期。

轮询也可能已由 ALooper_wake() 显式唤醒。

ALOOPER_POLL_WAKE

在超时过期之前,轮询使用 wake() 被唤醒,并且没有执行任何回调,也没有其他文件描述符就绪。

匿名枚举 50

android/looper.h 中声明
 Anonymous Enum 50

looper 可以监控的文件描述符事件标志。

这些标志位可以组合使用以同时监控多个事件。

属性
ALOOPER_EVENT_ERROR

文件描述符遇到了错误条件。

looper 始终发送关于错误的通知;无需在请求的事件集合中指定此事件标志。

ALOOPER_EVENT_HANGUP

文件描述符已挂起。

例如,表示管道或套接字的远程端已关闭。

looper 始终发送关于挂起的通知;无需在请求的事件集合中指定此事件标志。

ALOOPER_EVENT_INPUT

文件描述符可用于读取操作。

ALOOPER_EVENT_INVALID

文件描述符无效。

例如,文件描述符过早关闭。

looper 始终发送关于无效文件描述符的通知;无需在请求的事件集合中指定此事件标志。

ALOOPER_EVENT_OUTPUT

文件描述符可用于写入操作。

类型定义

ALooper

android/looper.h 中声明
struct ALooper ALooper

ALooper。

looper 是用于跟踪线程事件循环的状态。Looper 不定义事件结构或其他此类内容;相反,它们是一种更低级别的设施,用于附加一个或多个离散对象以监听事件。这里的“事件”仅仅是文件描述符上的可用数据:每个附加对象都有一个关联的文件描述符,等待“事件”意味着(内部)轮询所有这些文件描述符,直到其中一个或多个有可用数据。

一个线程只能关联一个 ALooper。

ALooper_callbackFunc

android/looper.h 中声明
int(* ALooper_callbackFunc)(int fd, int events, void *data)

对于基于回调的事件循环,这是文件描述符事件发生时调用的函数原型。

它被赋予与其关联的文件描述符、触发的轮询事件的位掩码(通常是 ALOOPER_EVENT_INPUT)以及最初提供的数据指针。

实现应返回 1 以继续接收回调,或返回 0 以使此文件描述符和回调从 looper 中注销。

变量

信息

android/looper.h 中声明
int ALooper_pollAll may ignore wakes Use ALooper_pollOnce instead See The API documentation for more information

函数

ALooper_acquire

android/looper.h 中声明
void ALooper_acquire(
  ALooper *looper
)

获取给定 ALooper 对象的引用。

这会阻止对象被删除,直到引用被移除。只有在安全地将 ALooper 从一个线程传递到另一个线程时才需要这样做。

ALooper_addFd

android/looper.h 中声明
int ALooper_addFd(
  ALooper *looper,
  int fd,
  int ident,
  int events,
  ALooper_callbackFunc callback,
  void *data
)

向 looper 添加一个新的文件描述符以便进行轮询。

如果之前添加了相同的文件描述符,它将被替换。

“fd”是要添加的文件描述符。“ident”是此事件的标识符,它从 ALooper_pollOnce() 返回。标识符必须 >= 0,或者在提供非 NULL 回调时为 ALOOPER_POLL_CALLBACK。“events”是唤醒轮询的事件。通常这是 ALOOPER_EVENT_INPUT。“callback”是当文件描述符上发生事件时要调用的函数。“data”是提供给回调的私有数据指针。

此函数有两个主要用途:

(1) 如果“callback”是非 NULL,则当文件描述符上有数据时,将调用此函数。它应执行任何待处理的事件,并适当地从文件描述符中读取数据。在这种情况下,'ident' 会被忽略。

(2) 如果“callback”是 NULL,则当文件描述符有可用数据时,ALooper_pollOnce 将返回 'ident',要求调用者负责处理它。

如果文件描述符已添加则返回 1,如果发生错误则返回 -1。

此方法可以在任何线程上调用。如果需要唤醒轮询,此方法可能会短暂阻塞。

ALooper_forThread

android/looper.h 中声明
ALooper * ALooper_forThread()

返回与调用线程关联的 looper,如果没有则返回 NULL。

ALooper_pollAll

android/looper.h 中声明
int ALooper_pollAll(
  int timeoutMillis,
  int *outFd,
  int *outEvents,
  void **outData
) __REMOVED_IN(1

类似于 ALooper_pollOnce(),但会执行所有待处理的回调,直到所有数据已被消费或某个文件描述符可用但没有回调。

此函数永远不会返回 ALOOPER_POLL_CALLBACK。

此 API 无法可靠地响应 ALooper_wake。因此,此 API 是隐藏的,调用者应迁移到 ALooper_pollOnce。保留二进制兼容性是为了支持已编译的应用。

已弃用。 应将对 ALooper_pollAll() 的调用替换为 ALooper_pollOnce()。如果您在循环中调用 ALooper_pollOnce(),则必须将所有返回值视为也表示 ALOOPER_POLL_WAKE。

ALooper_pollOnce

android/looper.h 中声明
int ALooper_pollOnce(
  int timeoutMillis,
  int *outFd,
  int *outEvents,
  void **outData
)

等待事件可用,可以选择设置超时时间(以毫秒为单位)。

为发生事件的所有文件描述符调用回调。

如果超时为零,则立即返回而不阻塞。如果超时为负数,则无限期等待直到出现事件。

所有返回值也可能暗示 ALOOPER_POLL_WAKE。 如果您在循环中调用此函数,则必须将所有返回值视为也表示 ALOOPER_POLL_WAKE。

如果在超时过期之前使用 ALooper_wake() 唤醒了轮询,并且没有调用任何回调,也没有其他文件描述符就绪,则返回 ALOOPER_POLL_WAKE。

如果调用了一个或多个回调,则返回 ALOOPER_POLL_CALLBACK。轮询也可能已由 ALooper_wake 显式唤醒。

如果在给定的超时过期之前没有数据,则返回 ALOOPER_POLL_TIMEOUT。轮询也可能已由 ALooper_wake 显式唤醒。

如果调用线程没有关联的 Looper 或发生无法恢复的内部错误,则返回 ALOOPER_POLL_ERROR。轮询也可能已由 ALooper_wake 显式唤醒。

如果文件描述符有数据且没有回调函数(需要调用者在此处处理),则返回一个 >= 0 的值,其中包含一个标识符(与传递给 ALooper_addFd()ident 标识符相同)。在此(且仅在此)情况下,outFd、outEvents 和 outData 将包含与文件描述符关联的轮询事件和数据,否则它们将被设置为 NULL。轮询也可能已由 ALooper_wake 显式唤醒。

此方法不会返回,直到为所有已通知的文件描述符调用了相应的回调函数。

ALooper_prepare

android/looper.h 中声明
ALooper * ALooper_prepare(
  int opts
)

准备与调用线程关联的 looper,并返回它。

如果线程已经有一个 looper,则返回该 looper。否则,将创建一个新的 looper,并将其与线程关联并返回。

opts 可以是 ALOOPER_PREPARE_ALLOW_NON_CALLBACKS 或 0。

ALooper_release

android/looper.h 中声明
void ALooper_release(
  ALooper *looper
)

删除先前使用 ALooper_acquire() 获取的引用。

ALooper_removeFd

android/looper.h 中声明
int ALooper_removeFd(
  ALooper *looper,
  int fd
)

从 looper 中移除先前添加的文件描述符。

此方法返回后,可以安全地关闭文件描述符,因为 looper 将不再引用它。但是,如果文件描述符已经发出信号,回调函数可能已经在运行或最后一次运行。调用代码负责确保安全处理这种情况。例如,如果回调函数在自身执行期间通过返回 0 或调用此方法来移除自身,则可以保证除非重新注册,否则以后不会再次调用它。

如果文件描述符被移除则返回 1,如果之前没有注册则返回 0,如果发生错误则返回 -1。

此方法可以在任何线程上调用。如果需要唤醒轮询,此方法可能会短暂阻塞。

ALooper_wake

android/looper.h 中声明
void ALooper_wake(
  ALooper *looper
)

异步唤醒轮询。

此方法可以在任何线程上调用。此方法会立即返回。