Handler消息传递机制之Looper
来源:互联网 发布:创意艺术大学吧 知乎 编辑:程序博客网 时间:2024/06/05 19:57
Android的消息处理有四个核心类:Handler,Looper,Message,MessageQueue,都在android.os包中。
首先分析线程的魔法师Looper:
Looper的字面意思是“循环者”,它被设计用来使一个普通线程编程Looper线程。Looper线程就是循环工作的线程,一旦有新任务就执行,执行完后继续等待下一个任务,这就是Looper线程,使用Looper类创建Looper线程很简单,代码如下:
public class LooperThread extends Thread{
@Override
public void run(){
//将当前线程初始化为Looper线程
Looper.prepare();
public void handleMessage(Message msg){
super.handlerMessage(msg);
switch(msg.what){
case 0:
break;
default:
break;
}
}
//开始循环处理消息队列
Looper.loop();
}
}
通过上面两行核心代码(Looper.prepare()和Looper.loop()),普通线程就升级为Looper线程了,接下来分析这两行代码做了什么
Looper.prepare()将一个普通Thread初始化为LooperThread,这个LooperThread中有一个Looper对象,在Looper对象的内部维护了一个消息队列MessageQueue,注意,一个线程只能有一个Looper对象。why? 下面看源码:
public class Looper{
//每个线程中的Looper对象其实是一个ThreadLocal,即线程本地存储对象(TLS)(突然想到orm,好吧,我的思想太发达了,orm就是object reflect model,对象反射模型)
private static final ThreadLocal sThreadLocal=new ThreadLocal();
//Looper内的消息队列
final MessageQueue mQueue;
//当前线程
Thread mThread;
//每个Looper对象中有它的消息队列和它所属的线程
private Looper(){
mQueue=new MesaageQueue();
mRun=true;
mThread=Thread.currentThread();
}
//当我们调用的该方法会在调用线程的TLS中创建Looper对象
public static final void prepare(){
if(sThreadLocal.get()!=null){
//如果在有Looper对象的线程中再次创建Looper对象就会抛出异常
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
}
通过上面的源码就可以清楚的看出Looper.prepare()背后的工作方式了,核心就是把Looper对象定义为ThreadLocal.
接下来就是Looper.loop(),调用这个方法后,它就会不断的从Looper对象内部维护的那个消息队列MQ中取出队头的消息(也叫任务)执行。
源码分析如下:
public static final void loop(){
Looper me=myLooper();//得到当前线程的Looper
MessageQueue queue=me.mQueue;//得到当前looper的消息队列MQ
final long ident=Binder.clearCallingIdentity();
//开始循环
while(true){
Message msg=queue.next();//取出message
if(msg!=null){
if(msg.target==null){
//message没有target,为结束信号,退出循环
return;
}
//很重要,将真正的处理工作交给message的target,也就是Handler.
msg.target.dispatchMessage(msg);
//回收message资源
msg.recycle();
}
}
}
除了prepare()和loop()还有一些其他的有用的方法
Looper.myLooper()得到当前线程的Looper对象。
源码如下:
public static final Looper myLooper(){
//在任意线程调用Looper.myLooper()返回的都是那个线程的Looper对象
return (Loopert)sThreadLocal.get();
}
getThread()得到Looper对象所属线程
public Thread getThread(){
return mThread;
}
quit()结束Looper循环
public void quit(){
//创建一个新的Message,它的target为null,表示结束循环消息
Message msg=Message.obtain();
//发出消息
mQueue.enqueueMessage(msg,0);
}
总结:
1.每个线程有且最多只能有一个Looper对象,他是一个ThreadLocal
2.Looper内部有一个消息队列,loop()方法调用后线程开始不断的从消息队列中取出消息执行。
3.Looper使一个普通线程编程Looper线程。
- Handler消息传递机制之Looper
- Handler消息传递机制之Looper简介
- Handler,Looper消息传递机制
- Handler、Looper消息传递机制
- Handler、Looper消息传递机制
- Handler、Looper消息传递机制
- Handler、Looper消息传递机制-----浅析
- Android消息传递机制---Handler,MessageQueue,Looper.
- 安卓Handler,Looper消息传递机制
- 20、Handler、Looper消息传递机制
- 【Android开发】线程与消息处理-Handler消息传递机制之Looper
- Android消息机制之Looper和Handler
- Android消息机制之Looper、Handler、MessageQueen
- Handler消息传递机制(三)管理MessageQueue的Looper
- android-消息传递机制Message、MessageQueue、Handler、Looper
- android线程消息传递机制——Looper,Handler,Message
- android线程消息传递机制——Looper,Handler,Message
- 【Android基础笔记19】Handler、Looper消息传递机制
- romact.apk的总结
- 多项式求和算法
- base 64 加密解密 for test demo
- 随记-生活杂感
- navicat导入数据库
- Handler消息传递机制之Looper
- 解决Windows 7下Firefox下载入Localhost网站超慢办法
- Hibernate JPA 之关联映射
- linux中的livecd、liveDVD和其他安装方式简介
- 传智播客全新升级入主武汉金融港。
- MathType中关于箭头符号的那些秘密
- 一道zhangying机试题
- C++命名空间
- JSon对象、JSon数组和JSon字符串。