Looper中的睡眠等待与唤醒机制
C++类Looper中的睡眠和唤醒机制是通过pollOnce和wake函数提供的,它们又是利用操作系统(Linux内核)的epoll机制来完成的。当被监控的文件(通过epoll_ctl的EPOLL_CTL_ADD添加进去)可I/O时,epoll_wait调用会从睡眠中醒来,这时,可以检查是哪个(或哪些)文件描述符对应的文件可以进行I/O读写了,从而做出进一步处理。使用者利用它们就可以拥有睡眠等待和唤醒机制。下面详述。
在Looper的构造函数中,会创建一个管道(下面的行73),然后调用epoll_create获取一个epoll的实例的描述符(行88),最后将管道读端描述符作为一个事件报告项添加给epoll(行95)。这样,当管道读端有数据可读时,将会得到报告。Looper的构造函数如下(见文件Looper.cpp):
Looper的pollOnce函数将最终调用到其pollInner函数。在后者里面,将调用epoll_wait睡眠等待其监控的文件描述符是否有可I/O事件的到来,若有(哪怕只有一个),epoll_wait将会醒来,然后可检查是哪个文件描述符上的可I/O事件。pollInner函数中的相关代码如下(见文件Looper.cpp):
可见,在线程循环中调用了Looper的pollOnce函数,将导致睡眠等待在上面的行218处的epoll_wait上。当向消息队列发送消息并进行唤醒时,行218将被唤醒,因此从pollOnce函数中返回,可以从消息队列中取出消息进行处理。
Looper的wake函数用于向管道中写入字符(下面的行367),以唤醒pollOnce:
下面来看一下Java层的MessageQueue如何利用这种机制。
前面提到在android.os.MessageQueue的next函数中取出下一个消息时,会调用到native层实现的函数nativePollOnce时,实际调用到了如下native实现(见文件android_os_MessageQueue.cpp):
上面行157的pollOnce函数代码是(见文件android_os_MessageQueue.cpp):
这样,它们就通过Looper的pollOnce实现了在Looper中的管道上的读端上的睡眠等待。
当android.os.MessageQueue的enqueueMessage函数往队列上添加了一个新消息或removeSyncBarrier移除了同步屏障后,可能需要调用nativeWake唤醒,其native实现为:(见文件android_os_MessageQueue.cpp):
上面的行162调用的又是下面的函数,代码如下(见文件android_os_MessageQueue.cpp):
这样,Looper将向管道写端写入字符,唤醒其在管道读端上的睡眠等待。
因此,通过借助于Looper的wake和pollOnce函数,可以让别的消息队列(如Java层的消息队列)拥有睡眠唤醒机制:没有消息时pollOnce调用者将睡眠等待,有消息时让wake函数去唤醒睡眠等待。
本文节选自《深入剖析Android系统》一书
杨长刚著
电子工业出版社出版
相关推荐
Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,使用Looper....
所以在按按钮后,会等待3s后显示VIEW才会有打印输出,如果理解了Looper的同步机制后,可以删除3s等待和主线程中的post runnable使这个示例程序跑起来更加顺畅。希望对于Android初学者有所帮助。
详细描述了Android的消息处理机制中,Looper和handler类详解
Looper Count测试Looper个数工具apk
bootstrap-looper 模版 bootstrap-looper 模版 bootstrap-looper 模版
android源码中包含了大量的设计模式, 除此以外, android sdk还精心为我们设计了各种helper类, 对于和我一样渴望水平得到进阶的人来说, 都太值得一读了。 这不, 前几天为了了解android的消息处理机制, 我看 了...
Handler,AsyncTask,Looper自定义线程使用示例,自定义线程与UI线程交互,访问UI线程控件
Android 消息处理机制之四: 消息循环 Looper 及其源码解析 http://blog.csdn.net/ahuier/article/details/17103517
handler与looper及messagequeue的简单总结
Android Looper的详细介绍,、android初学者可以下载来看看
可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息. 3、Looper: 是Handler和消息队列之间通讯桥梁,程序组件首先通过...
关于Looper的使用,可以在任意2个线程间通讯。
Handler和looper详解.
Looper、Handler与HandlerThread相关概念与简介
个人购买的资源,仅供学习使用,请勿用做商业用途,流行的Bootstrap框架,用于后台管理,风格简约
当子线程中进行耗时操作后需要更新UI时,通过Handler将有关的UI操作切换到主线程中执行。 四要素: Message(消息):需要被传递的消息,其中包含了消息标识(what),消息处理数据和处理对象(arg1,arg2,obj),发送...
这次项目用到的主要是Handler Thread Looper,希望对这三者关系还不是很清楚的人能通过我的项目读懂,当然我也不敢保证一定能
Android应用程序消息处理机制(Looper、Handler)分析
Handler+Looper+MessageQueue
http://blog.csdn.net/lindonglian/article/details/43316239 不使用默认的looper