Handler和Looper区别与关系详解
2015-10-31 11:22
337 查看
1.什么是Handler,我就不再赘述了,Handler的主要功能就是发送消息,更新UI仅仅是handler线程间通信的一个应用,不能算作Handler的功能
发送消息,发送给谁?用什么方式?最关建的是Handler如何创建?
首先要普及一下线程创建和多线程安全的概念
如同大家说的一样,Looper,Handler,MessageQueue三者共同实现了Android系统里线程间通信机制,每一个应用程序打开都会开启一条线程,我们通常称其为主线程,
每一条线程都会在创建的时候拥有一个MessageQueue
多线程安全其实是指多条线程进行相同的操作引发的数据不一致问题,MessageQueue是保证多线程安全的方法,顾名思义,但此处的是可插入的队列,你更好的应该把它看成一个单向链表,MessageQueue根据指定时间进行排队;
那么问题来了,消息队列是由谁在操作和管理?
Handler的创建必须通过一个已经初始化的Looper对象,Handler Handler1=new Handler()//是调用当前线程的Looper去初始化Handler1;当然也就意味这Handlerd 的另外一个重载构造函数的存在Handler Handler1=new Handler(Looper looper)//使用指定的Looper创建Handler1;
2.Looper用于操作消息队列,Looper对象内部也包含一个空消息队列对象和空线程,通过Looper.prepare()初始化,可以让该空队列对象指向当前线程的消息队列,让空线程指向当前线程,这样Looper可以对MessageQueue进行操作,主线程在创建时会自动对Looper初始化,子线程必须手动初始化;
看到这里你大概也知道,Handler的消息发送给了自身的Looper,——如线程A要传递消息给线程B,则需要在线程A中去得到线程B的Handler,而在线程A中通过线程B的Handler,利用Post或者sendMessage(message)发送消息,到线程B的Looper,也就是线程B的MessageQueue中;
3.一个线程中可以存在多个该线程的Handler对象实例,但是只存在一个MessageQueue(消息队列),也就是只存在一个Looper,
由此可推断出一个线程的Looper是由该线程的多个Handler对象共享。
//常用Looper相关的函数
Looper.prepare(); //若缺失则抛出异常退出
静态函数
Looper.loop(); //运行这个线程的消息队列。
静态函数
HandlerThread.getLooper() //返回HandlerThread的Looper
HandlerThread.getThreadId() //返回线程的ID,也是对线程的唯一标识
Handler(Looper looper) //构造函数,使用指定的Looper构建Handler对象
static Looper getMainLooper() //Looperlei类的函数,返回应用程序的主线程;可实现在子线程代码中对UI更新的操作
子线程代码更新UI操作的方法
class LooperThread extends Thread {
public Handler mHandler;
public Handler handler1;//其他类或者线程通过LooperThread实例.handler1;获得LooperThread线程的Handler
private TextView t2;
public int x=21,y=21;
public Handler handler2=new Handler(Looper.getMainLooper()){//子线程代码中使用主线程进行更新UI操作
public void handleMessage(Message msg) {
if(msg.what==52)
t2.setText("grg1="+msg.arg1+"arg2="+msg.arg2);
};
};//用主线程实例化
LooperThread(Handler handler1,TextView t2){
this.handler1=handler1;
this.t2=t2;
}
public void run() {
Looper.prepare();//初始化,先让该消息队列指向当前线程的消息队列,让空线程也指向当前线程,
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
if(msg.what==1){
Message message=handler2.obtainMessage(52, x++, y++);
handler2.sendMessage(message);
}
}
};
Looper.loop();//运行消息队列
}
}
发送消息,发送给谁?用什么方式?最关建的是Handler如何创建?
首先要普及一下线程创建和多线程安全的概念
如同大家说的一样,Looper,Handler,MessageQueue三者共同实现了Android系统里线程间通信机制,每一个应用程序打开都会开启一条线程,我们通常称其为主线程,
每一条线程都会在创建的时候拥有一个MessageQueue
多线程安全其实是指多条线程进行相同的操作引发的数据不一致问题,MessageQueue是保证多线程安全的方法,顾名思义,但此处的是可插入的队列,你更好的应该把它看成一个单向链表,MessageQueue根据指定时间进行排队;
那么问题来了,消息队列是由谁在操作和管理?
Handler的创建必须通过一个已经初始化的Looper对象,Handler Handler1=new Handler()//是调用当前线程的Looper去初始化Handler1;当然也就意味这Handlerd 的另外一个重载构造函数的存在Handler Handler1=new Handler(Looper looper)//使用指定的Looper创建Handler1;
2.Looper用于操作消息队列,Looper对象内部也包含一个空消息队列对象和空线程,通过Looper.prepare()初始化,可以让该空队列对象指向当前线程的消息队列,让空线程指向当前线程,这样Looper可以对MessageQueue进行操作,主线程在创建时会自动对Looper初始化,子线程必须手动初始化;
看到这里你大概也知道,Handler的消息发送给了自身的Looper,——如线程A要传递消息给线程B,则需要在线程A中去得到线程B的Handler,而在线程A中通过线程B的Handler,利用Post或者sendMessage(message)发送消息,到线程B的Looper,也就是线程B的MessageQueue中;
3.一个线程中可以存在多个该线程的Handler对象实例,但是只存在一个MessageQueue(消息队列),也就是只存在一个Looper,
由此可推断出一个线程的Looper是由该线程的多个Handler对象共享。
//常用Looper相关的函数
Looper.prepare(); //若缺失则抛出异常退出
静态函数
Looper.loop(); //运行这个线程的消息队列。
静态函数
HandlerThread.getLooper() //返回HandlerThread的Looper
HandlerThread.getThreadId() //返回线程的ID,也是对线程的唯一标识
Handler(Looper looper) //构造函数,使用指定的Looper构建Handler对象
static Looper getMainLooper() //Looperlei类的函数,返回应用程序的主线程;可实现在子线程代码中对UI更新的操作
子线程代码更新UI操作的方法
class LooperThread extends Thread {
public Handler mHandler;
public Handler handler1;//其他类或者线程通过LooperThread实例.handler1;获得LooperThread线程的Handler
private TextView t2;
public int x=21,y=21;
public Handler handler2=new Handler(Looper.getMainLooper()){//子线程代码中使用主线程进行更新UI操作
public void handleMessage(Message msg) {
if(msg.what==52)
t2.setText("grg1="+msg.arg1+"arg2="+msg.arg2);
};
};//用主线程实例化
LooperThread(Handler handler1,TextView t2){
this.handler1=handler1;
this.t2=t2;
}
public void run() {
Looper.prepare();//初始化,先让该消息队列指向当前线程的消息队列,让空线程也指向当前线程,
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
if(msg.what==1){
Message message=handler2.obtainMessage(52, x++, y++);
handler2.sendMessage(message);
}
}
};
Looper.loop();//运行消息队列
}
}
相关文章推荐
- linux服务开机启动
- hadoop架构初步理解
- Storm Spark 和 Hadoop区别
- linux cp命令覆盖 无提示解决办法
- fedora 关闭 selinux 安全服务
- shell编程之if判断的总结
- Linux文件及目录操作
- iptables
- Mastering Nginx 笔记三----upstream模块解释
- 【Unified Auditing】统一审计的进程架构体系
- 编译内核和其他文件的linux命令
- Linux-grep学习笔记
- JIURL文档-Linux的虚拟内存与分页机制(x86-64位)(一)
- Linux内核协议栈-初始化流程分析
- 在被qiang之后如何使用Dropbox
- Linux 学习(1)-- 查看内核版本号及android系统属性
- CentOS 下安装Mplayer播放器(转载)
- 图像开发的p2s模式:halcon+opencv的联动
- Centos磁盘挂载操作
- codis linux 部署