【内核研究】处理者_Handler
虽然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的更多相关文章
- kernelchina.org内核研究
kernelchina.org 内核研究 转自:http://www.kernelchina.org
- PHP内核研究(内存管理1)
PHP内存管理 PHP在5.3之前采用的是引用计数法 PHP在5.3之后采用了新的垃圾回收机制 操作系统在申请内存空间的时候回引发系统调用 在操作系统申请内存空间的时候,会将CPU从用户态切换到内核态 ...
- SQLite剖析之内核研究
先从全局的角度把握SQLite内核各个模块的设计和功能.SQLite采用了层次化.模块化的设计,而这些使得它的可扩展性和可移植性非常强.而且SQLite的架构与通用DBMS的结构差别不是很大,所以它对 ...
- PHP内核研究:HASH表和变量 【转】
PHP HASH表 在PHP中,所有的数据 无论变量,常量,类,属性 都用Hash表来实现. 先要说说 HASH表 typedef struct bucket { ulong h; ...
- PHP内核研究 静态变量
静态变量 它可以是 静态全局变量,如果不调用unset,那么这个静态变量会一直存在,直到程序退出时才由Zend内存管理来释放 它可以是 静态局部变量:在函数里定义,函数执行完后,该静态变量不会消失 它 ...
- PHP内核研究
深入理解PHP内核:Think In PHP Internals(TIPI)是一个开源项目 ,分享PHP内部实现的细节,如内核,扩展等.官网见:http://www.php-internals.com ...
- perf---LINUX内核研究
http://blog.chinaunix.net/uid-10540984-id-3854969.html http://blog.csdn.net/bluebeach/article/detail ...
- linux内核研究-8-块设备I/O层
http://blog.csdn.net/rill_zhen/article/category/1123087
- Linux内核学习笔记
1.vanbreaker的专栏 2.LinuxKernel Exploration 3.DroidPhone的专栏 4.Linux内核研究以及学习文档和ARM学习以及研究的开放文档 [力荐] 5. ...
随机推荐
- [LUOGU] P2716 和谐的雪花
https://www.luogu.org/problemnew/show/P2716 给出一个n*m的矩形,求里面边长最小的正方形,使得该正方形内最大值与最小值的差大于等于给定的K. 第一反应是二分 ...
- [LUOGU] 1364 医院设置
设有一棵二叉树,如图: [我是图] 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为1.如 ...
- 如何用纯 CSS 创作一个记事本翻页动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/qKOPGw 可交互视频教 ...
- PERL学习之模式匹配
一.简介 模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即模式def.其用法如结合函数split将字符串用某模式分成多个单词:@array = split(/ /, $line); ...
- python--线程的其他方法
一 . current_thread的用法 import threading import time from threading import Thread, current_thread def ...
- Django中重定向页面的时候使用命名空间
urls.py from django.urls import path from . import views app_name='front' urlpatterns = [ path('',vi ...
- GIL 线程/进程池 同步异步
GIL 什么是GIL 全局解释器锁,本质是一把互斥锁,是加在cpython解释器上的一把锁, 同一个进程内的所有线程需要先抢到GIL锁,才能执行python代码 为什么要有GIL cpython解释器 ...
- (转) 苹果所有常用证书,appID,Provisioning Profiles配置说明及制作图文教程(精)
原文地址:http://blog.csdn.net/holydancer/article/details/9219333 概述: 苹果的证书繁锁复杂,制作管理相当麻烦,今天决定重置一个游戏项目中的所有 ...
- 在xcode上把你的app多语言国际化(NSLocalizedString)
1.到project->info->localizations 下面的加号,添加你需要的语言 千万不要删除 base 否虽然我不知道有什么用,我是删了整个storyboard没了,很 ...
- 循环神经网络与LSTM网络
循环神经网络与LSTM网络 循环神经网络RNN 循环神经网络广泛地应用在序列数据上面,如自然语言,语音和其他的序列数据上.序列数据是有很强的次序关系,比如自然语言.通过深度学习关于序列数据的算法要比两 ...