Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[问答]Looper中的loop是如何实现阻塞的? #245

Open
miao1007 opened this issue Sep 7, 2015 · 2 comments
Open

[问答]Looper中的loop是如何实现阻塞的? #245

miao1007 opened this issue Sep 7, 2015 · 2 comments

Comments

@miao1007
Copy link

miao1007 commented Sep 7, 2015

分析API22的源码,可以发现Loop操作如下

 for (;;) {
    Message msg = queue.next(); // might block
    if (msg == null) {
        return;
    }
    //处理Msg中实现的接口(Message/Ruunabe)
    msg.target.dispatchMessage(msg);    
    //...Logs and recycler
}

根据注释,我们可以知道next实现了阻塞,但是网上分析一般到这里就截止了,请问这里的Next是如何实现阻塞的呢?

@linroid
Copy link

linroid commented Sep 7, 2015

next()方法中还有一个循环:

for (;;) {
    if (nextPollTimeoutMillis != 0) {
        Binder.flushPendingCommands();
    }
    nativePollOnce(ptr, nextPollTimeoutMillis);

    //...
}

阻塞是发生在nativePollOnce方法,在native层使用了epoll机制来等待消息,可以看下这篇分析文章:
《深入理解Android 卷III》第二章 深入理解Java Binder和MessageQueue

Message被添加到队列中时,会根据when的执行时间排序,next()方法会一直等待到下一个消息的执行时间到来然后取出并返回。

@kyleinfo
Copy link

楼上说的很全,只补充一点,looper 本身就是为了解决ui的并发问题而使用的异步消息队列,通过不断的循环取消息然后通过 jni 分发到 native 方法进行处理

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants