Handler任务模型之Looper类分析

1. 介绍 上一节完成了对Message类的分析,在Handler消息模型中,Message类是对消息的封装体,本节要介绍的是Looper类,该类的作用是循环询问MessageQueue是否还有要执行的消息,然后将获取到的消息分发出去。

2. 源码分析 首先看下Looper类几个重要的属性信息

ThreadLocal sThreadLocal = new ThreadLocal();final MessageQueue mQueue;Thread mThread;private static Looper mMainLooper = null;

其中sThreadLocal 代表当前线程的ThreadLocal,mQueue代表该Looper关联的MessageQueue(一个Looper仅有一个MessageQueue关联),mThread代表当前的线程,mMainLooper代表UI线程的Looper 其中Looper的文档介绍这样构建一个新的Handler消息处理模型。

Thread { *public Handler mHandler; **public void run() { *Looper.prepare(); **mHandler = new Handler() { *public void handleMessage(Message msg) { *// process incoming messages here *} *}; **Looper.loop(); *} * }

所以我们首先看下Looper.prepare()方法

() {if (sThreadLocal.get() != null) {throw new RuntimeException(“Only one Looper may be created per thread”);}sThreadLocal.set(new Looper());}

第2行:从ThreadLocal尝试取Looper对象,如果不为空,就会抛出运行时异常,因为一个线程直接对应一个Looper对象,也就是prepare方法也只能被调用一次。这里通过Looper空构造创建的对象

private Looper() {mQueue = new MessageQueue();mRun = true;mThread = Thread.currentThread();}

其中主线程的mainLooper是通过prepareMainLooper方法定义的,内部也是调用Looper.prepare()方法完成Looper初始化操作,另外给myLooper起名为mainLooper而已。

() {prepare();setMainLooper(myLooper());if (Process.supportsProcesses()) {myLooper().mQueue.mQuitAllowed = false;}}

这样对Looper类属性进行赋值 接下来看Looper.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(); (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);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();}}}

我们可以看出10行-42行是一个while(true)死循环,一直调用MessageQueue的next方法获取消息,该方法当没有消息的时候会处于阻塞状态。当取到消息的时候就会通过24行msg.target.dispatchMessage(msg)回调到我们在Handler的callBack或者handleMessage()方法中的代码逻辑。 另外Looper类中比较重要的方法是quit方法

() {Message msg = Message.obtain();mQueue.enqueueMessage(msg, 0);}

note注释中也有说明,一般来说发送一个Message的动作是由一个Handler类完成的,这样一个Message对象就能对应一个Handler对象,,此处没有通过handler而是将Message直接添加到MessageQueue消息链表中,会被作为Looper停止的一个标志位,这点会在MessageQueue源码分析中说明。

3. 结束语 通过Looper类的分析,可以看出Looper类的主要作用是循环取消息和分发消息,关于Message的逻辑结构此类是不关心的,关于Message的逻辑结构是在MessageQueue这个类中定义的,下一节将对MessageQueue类进行分析!

使你疲倦的不是前面的高山,而是你鞋里的一粒沙子。

Handler任务模型之Looper类分析

相关文章:

你感兴趣的文章:

标签云: