android - 什么是 android 中的消息队列本机轮询?

android - what is message queue native poll once in android?

我知道线程有一个消息队列并且处理程序能够将可运行对象或消息推送给它们,但是当我使用 Android Studio 工具分析我的 android 应用程序时,有一个奇怪的过程:

android.os.MessageQueue.nativePollOnce

它使用 CPU 比所有其他进程都多。它是什么以及如何减少 CPU 花在上面的时间? 您可以在下面找到分析器结果。

简答:

nativePollOnce方法用于"wait"直到下一个Message可用。如果在此调用期间花费的时间很长,则您的主 (UI) 线程没有实际工作要做并等待下一个事件处理。不用担心。

解释:

因为"main"线程负责绘制UI和处理各种事件,所以Runnable有一个循环处理所有这些事件。 该循环由 Looper and its job is quite straightforward: it processes all Messages in the MessageQueue.

管理

一个Message is added to the queue for example in response to input events, as frame rendering callback or even your own Handler.post calls. Sometimes the main thread has no work to do (that is, no messages in the queue), which may happen e.g. just after finishing rendering single frame (the thread has just drawn one frame and is ready for the next one, just waits for a proper time). Two Java methods in the MessageQueue class are interesting to us: Message next() and boolean enqueueMessage(Message, long). Message next(), as its name suggest, takes and returns the next Message from the queue. If the queue is empty (and there's nothing to return), the method calls native void nativePollOnce(long, int) which blocks until a new message is added. At this point you might ask how does nativePollOnce know when to wake up. That's a very good question. When a Message is added to the queue, the framework calls the enqueueMessage method, which not only inserts the message into the queue, but also calls native static void nativeWake(long), if there's need to wake up the queue. The core magic of nativePollOnce and nativeWake happens in the native (actually, C++) code. Native MessageQueue utilizes a Linux system call named epoll, which allows to monitor a file descriptor for IO events. nativePollOnce calls epoll_wait on a certain file descriptor, whereas nativeWake writes to the descriptor, which is one of the IO operations, epoll_wait waits for. The kernel then takes out the epoll-waiting thread from the waiting state and the thread proceeds with handling the new message. If you're familiar with Java's Object.wait() and Object.notify() methods, you can imagine that nativePollOnce is a rough equivalent for Object.wait() and nativeWake for Object.notify(), except they're implemented completely differently: nativePollOnce uses epoll and Object.wait() uses futexLinux电话。值得注意的是 nativePollOnceObject.wait() 都不会浪费 CPU 周期,因为当线程进入任一方法时,它会出于线程调度目的而被禁用(引用 javadoc 中的 Object class)。但是,一些分析器可能会错误地将等待 epoll(甚至等待对象)的线程识别为 运行 并消耗 CPU 时间,这是不正确的。如果这些方法实际上浪费了 CPU 个周期,则所有空闲应用程序将使用 100% 的 CPU,加热并减慢设备速度。

结论:

您不必担心 nativePollOnce。它只是表明所有消息的处理已经完成,线程等待下一个消息。好吧,这只是意味着你不要给你的主线程太多的工作 ;)