Looper、Handler的关系(二)
来源:互联网 发布:网络机顶盒系统崩溃了 编辑:程序博客网 时间:2024/05/16 06:10
上篇文章只是简单的说明了一下Android中的消息处理机制原理是什么,接下来将详细探讨其中的几个关键类。首先是Looper类。
Looper、Handler的关系(一)
首先看看Looper是如何使用的。典型的使用looper的例子是这样的:
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler(Looper.myLooper()) {//将Handler绑定到LooperThread的Looper中。 public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }//在程序中某个地方直接调用:new LooperThread().start();
在上面的代码中,Looper类的两个方法被调用了,Looper.prepare()和Looper.loop();
一、prepare()
以下是Looper类prepare()方法的源码:
// sThreadLocal.get() will return null unless you've called prepare(). private static final ThreadLocal sThreadLocal = new ThreadLocal(); /** Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call * {@link #loop()} after calling this method, and end it by calling * {@link #quit()}. */ public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }ThreadLocal是Java中的线程局部变量类。该类有两个关键方法:set()和get(),分别是设置调用线程的局部变量和获取调用线程的局部变量。这两个方法的结果都是与调用这个函数的线程有关。
因此,prepare()方法会在调用的线程的局部变量中设置一个Looper对象。这个线程也就是上面的LooperThread线程(由于LooerThread线程中调用了prepare()方法)。
再来看看Looper的构造函数:
final MessageQueue mQueue; volatile boolean mRun; Thread mThread; private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread(); }构造函数只是创建了消息队列,并初始化了当前线程的Thread对象。
通过上面的分析,可以得到:在调用prepare()的线程中,创建了一个Looper对象,这个Looper对象被保存在了这个线程的局部变量中(ThreadLocal),同时,在Looper中,创建了一个消息队列。也就是说,prepare()方法,利用了线程的局部变量(ThreadLocal)机制,将线程与Looper关联上了。
二、loop()
以下是部分源码:
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); while (true) { Message msg = queue.next(); // might block //if (!me.mRun) { // break; //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } if (me.mLogging!= null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); msg.target.dispatchMessage(msg); if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf("Looper", "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycle(); } } } /** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ public static final Looper myLooper() {//返回保存在线程局部变量中的Looper对象。 return (Looper)sThreadLocal.get(); }在loop()方法中,
msg.target.dispatchMessage(msg);这行代码可能不太理解。msg.target实际就是Handler,在Message的源码中,target就是消息的Handler,回调handler的dispatchMessage方法。
通过对上面Looper源码的分析,可以概括Looper的作用:
1、封装消息队列。在创建Looper对象时就创建了,在循环中,从队列中获取消息等处理。
2、Looper的prepare方法,将此Looper与调用prepare方法的线程关联起来了。这个线程,也就是最终的处理线程,将二者绑在了一起。
3、loop方法,则是处理消息队列中的消息。
接下来,说明一下Looper、Message和Handler三者的关系:
*Looper中有一个Message队列,里面存储的是待处理的Message;
*Message中有一个Handler,这个Handler是用来处理Message消息的。
下一节将讨论Handler类。
- Looper、Handler的关系(二)
- 面试常客Handler详细解析(Handler与Looper、MessageQueue的关系)(二)
- Looper、Handler的关系(一)
- Looper、Handler的关系(三)
- Handler由浅入深(二)--Handler的实现原理以及Looper、Handler、Message三者之间的关系
- Handler、MessageQueue 、Looper的关系
- Handler与Looper的关系
- Handler,Message,Looper的关系
- Handler Looper MessageQueue 的关系
- handler和looper的关系
- 理解Handler、Looper、MessageQueue、Thread关系?二
- Android Handler,Looper,MessageQueue关系(讲解比较透彻的)
- Activity/MessageQueue/Handler/Looper之间的关系
- Handler,Looper,Thread之间的关系
- Andriod中Handler,Looper,MessageQueue的关系
- 详解Handler和Looper的关系
- Looper, messageQueue和Handler的关系
- Handler Looper Message MessageQueue 的关系
- 光影集:双屏翻盖商务机 飞利浦V989 对比 三星W2014
- 如何设计玩家体验评估模型
- leetcode Remove Elements
- 一些我推荐的和想上的网络课程(Coursera, edX, Udacity,MIT OCW)
- HDWiki数据库结构说明
- Looper、Handler的关系(二)
- 装饰器模式浅谈
- 动态申请空间malloc
- 第二周 项目四 图书馆的书
- MongoDB 导入与导出
- js制作动态创建table行与修改等编辑表单功能特效
- SeeKBar 背景图片偏移的问题
- 数据挖掘常用算法简介
- Linux下JLink提示clone,插上JLink后会掉固件