Handler的概念

  顾名思义,handler在英语中是“操作着,处理者的意思”,而官方的文档给出的概念是,handler允许你发送或者处理Message对象或者Runable对象,这两个对象都是与线程的Message queue相关联的。每一个handler的实例(一个线程中可以有多个)都与单个的线程和那个线程对应的Messagequeue 关联,而处理的先后则按照发送消息的先后,先进先出进行处理。

根据自己的理解,handler主要负责message的发送与消息的处理。

如下面例子     Handler handler=new Handler();//负责允许runable对象

	Handler handler1 = new Handler()//负责接受message对象
{
public void handleMessage(Message msg) { System.out.println("hanler1:run"+Thread.currentThread().getId());
}
};
Runnable r=new Runnable(){ //这个runable对象,将在别的线程中执行
@Override
public void run() {
Message m = handler1.obtainMessage(); handler.post(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
System.out.println("handler2"+Thread.currentThread().getId()); }});
m.sendToTarget();
} };

  

Thread t=new Thread (r); //执行上面的runable
t.start();

我们来先看看结果:

从上面结果来看,可以得出一点结论,那就是不管是Message还是runable对象,虽然是在别的线程通过handler发送消息,但是handler接到消息后,处理过程还是在handler所在的那个线程中(也就是本例中的主线程中)

在网上有些文章说,Message和runable是又两个队列来管理的,其实不是,我们不妨将

m.sendToTarget();移到
handler.post的前面
Runnable r=new Runnable(){
@Override
public void run() {
Message m = handler1.obtainMessage();
m.sendToTarget();//这个移到前面
handler.post(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
System.out.println("handler threadid="+Thread.currentThread().getId()); }}); } };

发现结果:

hanler1先执行了,说明,他们共用的一个队列。

实际上Looper通过从Message queue从取出一个message,然后由优先级的从高到底判断

message的类型,有三种类型(     1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;
                    2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;
                    3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。)

Looper的概念

根据官方文档的概念(Class used to run a message loop for a thread.)用来为线程处理消息循环

而线程中默认是没有Looper的。为了给一个线程创建looper,执行Looper.prepar() 和Looper.loop()

实现如下

class LooperThread extends Thread {
public Handler mHandler; public void run() {
Looper.prepare(); mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
}; Looper.loop();
}
}

Looper在执行loop()里面处理消息

有人说为啥主线程里面没有Looper.prepare() 和Looper.loop()呢,其实系统已经为主线程默认添加了这两个方法,所以在主线程中,我们可以直接初始化handler。

而且如果你要自定义实现looper之后,必须在线程退出的时候,调用Looper.quit()。

下面再总结下:

每一个线程都可以包含一个Looper和一个消息队列

在android中ui线程(也即主线程)默认有一个Looper和消息队列

并且每一个Handler都有一个对应得message queue,而且一个线程中只有一个message queue,通过handler向message queue 发送消息,有两种方式发送sendMessage,和post

两者都可以更新UI线程。

经过测试,handler在哪个线程里面,不管是发送给他的message还是runale都在相对应的那个handler线程里面执行(一般是 主线程)

http://mobile.51cto.com/abased-375243.htm这篇文章上面说的有问题

最新文章

  1. 百度地图API 定位一直4.9E-324
  2. teambition的热血团队
  3. 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息
  4. poj 1463 Strategic game DP
  5. 操作JNI函数以及复杂对象传递
  6. mac os使用homebrew来管理后台服务
  7. lru cache java
  8. Bzoj 2346: [Baltic 2011]Lamp dijkstra,堆
  9. 【给你几个使用Xamarin的理由】
  10. IO库 8.1
  11. 办公用品管理系统VB——模块
  12. python学习笔记—Day1
  13. Elasticsearch学习笔记(四)ElasticSearch分布式机制
  14. for循环中break与continue的区别
  15. 获取SQL数据库表空间结构
  16. 安装Thinkphp5
  17. metasploit出错信息:can't allocate memory
  18. python学习笔记(五)---sublime text 多行代码注释快捷键
  19. Wait--常见的等待类型
  20. flask上传图片或者文件

热门文章

  1. 黑马程序员——经典C语言程序设计100例
  2. bundle install rake-10.4.2
  3. 60个响应式的Web设计教程–能够手机访问!
  4. NServiceBus教程-消息传递与处理
  5. 20151227感知机(perceptron)
  6. ios8 下请求读取通讯录权限 (网上众多资料漏下得一个坑)
  7. openstack neutron
  8. HP ILO2 使用详细教程
  9. 利用AuthorizeAttribute属性简单避免 MVC 中的跨域攻击
  10. 第二百三十二天 how can I 坚持