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这篇文章上面说的有问题

handler looper 和 线程的更多相关文章

  1. Android的消息机制: Message/MessageQueue/Handler/Looper

    概览   * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...

  2. Android之消息机制Handler,Looper,Message解析

    PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...

  3. 讲讲Handler+Looper+MessageQueue 关系

    Handler+Looper+MessageQueue这三者的关系其实就是Android的消息机制.这块内容相比开发人员都不陌生,在面试中,或者日常开发中都会碰到,今天就来讲这三者的关系. 概述: H ...

  4. Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别?

    一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...

  5. Handler Looper 原理 详解

    演示代码 public class MainActivity extends ListActivity {     private TextView tv_info;     private CalT ...

  6. new Handler()和new Handler(Looper.getMainLooper())的区别

    一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...

  7. android学习11——Handler,Looper,MessageQueue工作原理

    Message是Handler接收和处理的消息对象. 每个线程只能拥有一个Looper.它的loop方法读取MessageQueue中的消息,读到消息之后就把消息交给发送该消息的Handler进行处理 ...

  8. Handler,Looper,MessageQueue流程梳理

    目的:handle的出现主要是为了解决线程间通讯. 举个例子,android是不允许在主线程中访问网络,因为这样会阻塞主线程,影响性能,所以访问网络都是放在子线程中执行,对于网络返回的结果则需要显示在 ...

  9. Handler Looper 解析

    文章讲述Looper/MessageQueue/Handler/HandlerThread相关的技能和使用方法. 什么是Looper?Looper有什么作用? Looper是用于给线程(Thread) ...

随机推荐

  1. linux设置主机名

    第一种方式: hostname 在hostname 命名后面直接加想要更改的主机名,修改成功,键入hostname可以查看修改后的主机名,此种方式会立即生效,但是重启后还原.不会永久修改 第二种方式: ...

  2. 关于python中的unicode字符串的使用

    基于python2.7中的字符串: unicode-->编码encode('utf-8')-->写入文件 读出文件-->解码decode('utf-8')-->unicode ...

  3. Tilera 服务器上hadoop单机版测试

    ---恢复内容开始--- 本篇博客用来记录在单个Tilera服务器上安装hadoop并且测试的经历,参阅了大多数博客. 1.Tilera服务器介绍 本Tilera服务器配备9核CPU,共挂在6块硬盘, ...

  4. 在CENTOS下安装ORACLE 11g(LT项目开发参考)

    前段时间为K3CLOUD项目安装ORACLE服务器,因有同事对LINUX和ORACLE不熟,现整理文档,方便后面维护人员参考 ORACLE的安装 1.首先安装依赖包(新安装的centos需要,现服务器 ...

  5. 老 base64 for xe8

    not recommend ,only for study procedure TForm1.Button3Click(Sender: TObject); var ssi, sso: TStringS ...

  6. Kali Linux 安装教程-转

    rootoorotor昨天折腾了 Kali Linux 1.0,把大概的配置过程记录下来,希望对想接触或使用Kali Linux的同学有所帮助.   请注意: 1.本文为面向新手的教程,没技术含量,没 ...

  7. vim插件开发初步

    [vim插件开发初步] 将如下代码存在helloworld.vim, 放在~/.vim/plugin目录下,插件即可生效.:w保存代码后, 用:source命令执行后,也可以使用Helloworld命 ...

  8. SFTPTool 和 FTPTooL.java

    两个工具类依赖的jar包: FTPTool.java public static void main(String[] args) throws Exception{ FTPTooL ftpTool ...

  9. hdu 2819 Swap

    Swap http://acm.hdu.edu.cn/showproblem.php?pid=2819 Special Judge Problem Description Given an N*N m ...

  10. jgroups 常见概念

    组播(Multicast)传输:在发送者和每一接收者之间实现点对多点网络连接. 单播(Unicast)传输:在发送者和每一接收者之间实现点对点网络连接. 广播(Broadcast)传输:是指在IP子网 ...