handler looper 和 线程
来源:互联网 发布:网络市场结构特征分析 编辑:程序博客网 时间:2024/06/11 02:12
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());
}
};<br>
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); //执行上面的runablet.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 和 线程
- 线程中Handler和Looper的理解
- android开发 handler和looper 线程通信
- UI线程、Looper、Handler
- 线程 (Handler、Looper、MessageQueue和Thread的理解)
- handler和looper在子线程的调用
- Handler 和 Looper 来满足线程间的通信
- 线程间通信Handler,Looper,MessageQueue和Queue
- Looper,Handler,Message Queue和线程之间的那些事
- Android线程通信:Handler,MessageQueue和Looper原理分析
- Handler,Looper用法和主线程子线程间通信
- 安卓线程消息handler和looper相关内容
- Looper和Handler
- Looper和Handler
- android looper和handler
- Android Looper和Handler
- Android Looper和Handler
- android handler和looper
- Xcode中 工程全局宏与预处理 的配合使用
- Raft系列文章之一: 什么是Raft?
- [LeetCode]145.Binary Tree Postorder Traversal
- _exit和exit的区别?
- 【.NET机房重构】——注释新解
- handler looper 和 线程
- 使用指针实现字符串复制
- 整理一些ps4的DNS
- 取长补短
- 服务器×××上的MSDTC不可用解决办法
- OpenStack 网络项目(Neutron)的历史、现状与未来
- nyoj-198-数数
- 软件工程——宏观认识
- android 播放音频----Vitamio API for Android : MediaPlayer