虽然MessageQueue提供了直接读/写的函数接口。但对于程序猿来说,一般不直接读/写消息队列。之前了解到,在Looper.loop()函数中。当取出消息后,会回调msg.target对象的handleMessage()函数。而msg.target的类型正是Handler。

    /**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
//if (!me.mRun) {
// break;
//}
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}

一般使用Handler类向消息队列中发送消息,并重载Handler类的handleMessage()函数加入消息处理代码。

Handler对象仅仅能加入到有消息队列的线程中,否则会发生异常。以下代码是Handler类的构造函数:

    /**
* Default constructor associates this handler with the queue for the
* current thread.
*
* If there isn't one, this handler won't be able to receive messages.
*/
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
} mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}

注意这句代码:

        mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}

由以上代码能够得出结论,在构造Handler对象前。必须已经运行过Looper.prepare(),但prepare()不能被运行两次。

以下是Looper.prepare()的代码:

     /** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
* {@link #loop()} after calling this method, and end it by calling
* {@link #quit()}.
*/
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}

创建Handler对象能够在运行Looper.loop()函数之前。也能够在运行之后。

在以往的应用程序开发中,一般在Activity的初始化代码中加入Handler对象。其实,在Activity对象被构造前,Activity所在的线程已经运行了Looper.prepare()函数。详细可查看以下的链接。

http://blog.csdn.net/manoel/article/details/39499747

一个线程中能够包括多个Handler对象。在Looper.loop()函数中。不同的Message相应不同的Handler对象,从而回调不同的handleMessage()函数。

【内核研究】处理者_Handler的更多相关文章

  1. kernelchina.org内核研究

    kernelchina.org 内核研究 转自:http://www.kernelchina.org

  2. PHP内核研究(内存管理1)

    PHP内存管理 PHP在5.3之前采用的是引用计数法 PHP在5.3之后采用了新的垃圾回收机制 操作系统在申请内存空间的时候回引发系统调用 在操作系统申请内存空间的时候,会将CPU从用户态切换到内核态 ...

  3. SQLite剖析之内核研究

    先从全局的角度把握SQLite内核各个模块的设计和功能.SQLite采用了层次化.模块化的设计,而这些使得它的可扩展性和可移植性非常强.而且SQLite的架构与通用DBMS的结构差别不是很大,所以它对 ...

  4. PHP内核研究:HASH表和变量 【转】

    PHP HASH表 在PHP中,所有的数据 无论变量,常量,类,属性 都用Hash表来实现. 先要说说 HASH表 typedef struct bucket { ulong h;           ...

  5. PHP内核研究 静态变量

    静态变量 它可以是 静态全局变量,如果不调用unset,那么这个静态变量会一直存在,直到程序退出时才由Zend内存管理来释放 它可以是 静态局部变量:在函数里定义,函数执行完后,该静态变量不会消失 它 ...

  6. PHP内核研究

    深入理解PHP内核:Think In PHP Internals(TIPI)是一个开源项目 ,分享PHP内部实现的细节,如内核,扩展等.官网见:http://www.php-internals.com ...

  7. perf---LINUX内核研究

    http://blog.chinaunix.net/uid-10540984-id-3854969.html http://blog.csdn.net/bluebeach/article/detail ...

  8. linux内核研究-8-块设备I/O层

    http://blog.csdn.net/rill_zhen/article/category/1123087

  9. Linux内核学习笔记

    1.vanbreaker的专栏 2.LinuxKernel Exploration 3.DroidPhone的专栏 4.Linux内核研究以及学习文档和ARM学习以及研究的开放文档   [力荐] 5. ...

随机推荐

  1. mysql:10道mysql查询语句面试题

    表结构 学生表student(id,name) 课程表course(id,name) 学生课程表student_course(sid,cid,score) 创建表的sql代码 ```sql creat ...

  2. 【Gradle】Downloading https://services.gradle.org/distributions/gradle-3.3-bin.zip 失败

    提示连接超时 Downloading https://services.gradle.org/distributions/gradle-3.3-bin.zip 失败 这时候需要单独去官网下载包,然后放 ...

  3. CSS3的border-image

    border-image:none|image-url|number|percentage|stretch,repeat,round 参数: none:默认,无背景图片 url:地址,可以为绝对,也可 ...

  4. 杭电 1051 Wooden Sticks

    Description There is a pile of n wooden sticks. The length and weight of each stick are known in adv ...

  5. PAT Basic 1038

    1038 统计同成绩学生 本题要求读入N名学生的成绩,将获得某一给定分数的学生人数输出. 输入格式: 输入在第1行给出不超过10^5^的正整数N,即学生总人数.随后1行给出N名学生的百分制整数成绩,中 ...

  6. django的rest framework框架——安装及基本使用

    一.django的FBV 和 CBV 1.FBV(基于函数的视图): urlpatterns = [ url(r'^users/', views.users), ] def users(request ...

  7. Django模板语言中的自定义方法filter过滤器实现web网页的瀑布流

    模板语言自定义方法介绍 自定义方法注意事项 Django中有simple_tag 和 filter 两种自定义方法,之前也提到过,需要注意的是 扩展目录名称必须是templatetags templa ...

  8. 【03】Chrome提示印象笔记剪藏插件"已停用不支持的扩展程序"怎么办?

    [03] Chrome提示印象笔记剪藏插件"已停用不支持的扩展程序"怎么办? 刚好也遇上了这个问题,百度了一下,以下是解决方法,亲测可行: 1.首先把需要安装的第三方插件,后缀.c ...

  9. python 配置opencv-python 接口

    anaconda2下配置opencv-python 接口,import cv2遇到no cv2 模块问题,解决办法是将cv2.so放到anaconda2/lib/python2.7/site-pack ...

  10. hdu2084

    老题目了 #include <stdio.h> int main(){ ][]; int i,j,max; int c,n; scanf("%d",&c); w ...