V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Registering
V2EX  ›  Android

请教一个 Looper 的细节

  •  
  •   Registering · 2015-11-10 23:12:56 +08:00 · 8463 次点击
    这是一个创建于 3297 天前的主题,其中的信息可能已经有所发展或是发生改变。
    for (;;) {
              Message msg = queue.next(); // might block
                if (msg == null) {
                    // No message indicates that the message queue is quitting.
                    return;
                }
    
          //省去其他代码,,,
    

    如上代码,该循环是在 looper 类中的 loop 方法,相信大家都很熟,
    轮询发现 messagequeue 中没有消息后,会退出该循环,返回 looper 方法,,,那么下次有新的消息后,从哪里重新启动这个 loop 循环?

    5 条回复    2015-11-11 09:37:52 +08:00
    miao1007
        1
    miao1007  
       2015-11-10 23:17:35 +08:00
    next 阻塞实际上是使用 native 层的 Unix 的 epoll 实现的。

    nativePollOnce 读取管道,如果没有数据就阻塞

    nativeWake 向管道中写入 W 数据
    miao1007
        2
    miao1007  
       2015-11-10 23:18:27 +08:00
    你这个问题很好,我以前也问过[Looper 中的 loop 是如何实现阻塞的]( https://github.com/android-cn/android-discuss/issues/245)
    kifile
        3
    kifile  
       2015-11-11 08:17:46 +08:00
    你需要知道的是 Android 的主程序的真正入口并不是 Activity 或者 Application ,而是 ActivityThread.在 ActivityThread 中有一个 main 方法, public static 的哦,他就是主入口,在那里对 Looper 的 mainLoop 做了初始化,并进入死循环。
    Registering
        4
    Registering  
    OP
       2015-11-11 09:07:44 +08:00
    @kifile
    这个了解,,,
    但是这个死循环对消息队列为空的情况是有特殊处理的,,
    kifile
        5
    kifile  
       2015-11-11 09:37:52 +08:00   ❤️ 1
    可是这个特殊处理的目的是为了退出循环啊,要知道一般而言 Looper 中的 MessageQueue 对象只能是通过 Handler 传递消息进去, Handler 中有机制保证他始终不为空。

    而为空的情况就是调用了 Looper 中的 quit 方法,然后会调用 MessageQueue 中的 removeAllFutureMessagesLocked ,这个方法里才会将下一个 message 置为 null,导致循环结束。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1991 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 16:19 · PVG 00:19 · LAX 08:19 · JFK 11:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.