Android笔记(一 Looper)

来源:互联网 发布:诲汝知之乎悔的读音 编辑:程序博客网 时间:2024/06/05 19:41

Looper类分析

Looper、Thread、Handler以及MessageQueue是Android通信中消息机制中几个关键点,我们常常会用下面的图来表示他们之间的关系,以及构成的整个Android消息机制

这里写图片描述
在上图中,Handler发送Message到MessageQueue中,通过Looper循环取出消息,完成整个消息传输。
本章主要介绍Looper类。我们知道在主线程中,不需要我们创建Looper,系统会自动给我们创建好一个Looper。而子线程只能通过prepare()–>loop()的方法来手动创建。对于Looper的获取,这里需要注意。主线程的Looper可以直接通过Looper.getMainLooper()的方法来获取到,而子线程的Looper需要通过HandlerThread类中的getLooper方法来获取到。
事实上,对于主线程而言,系统会自动给我们执行prepare()–>loop()方法。这个过程在ActivityThread中通过main()方法中的Looper.prepareMainLooper()以及Looper.loop方法执行的操作,如图中5205行以及5221行所示。
这里写图片描述
在prepareMainLooper()方法中,主要是执行prepare(false)的操作,其中false参数表示该Looper不能被打断。
这里写图片描述
此外,刚方法中还会走一步获取sMainLooper对象的步骤。对于子线程的Looper而言,该变量为null,因为子线程不会走上述方法,因而不会给sMainLooper赋值。而对于主线程而言,就会给其赋值,而myLooper()方法实际上就是获取Looper中私密数据的数据,其他线程访问不到
这里写图片描述
而这个数据是在prepare中被设置,所以prepare中就干了这件事情,把new出来的Looper对像保存在sThreadLocal中,
这里写图片描述
而至于为什么我们每次都说要先prepare,再能loop(),下面具体分析loop()方法中所做的工作,我们就知道啦。从刚开始的部分我们就清楚地知道,事先没有prepare将会导致抛出异常,而且消息队列MessageQueue也在这个地方会被赋值。事实上,Looper类中的mThread、mMessageQueue属性的赋值是在new Looper()时被创建的,而这就是在prepare()中完成的。
这里写图片描述
接下来将会走到死循环中,除非获取不到消息,此时就会跳出来,在等待消息到来的时候,代码会阻塞在queue.next()这一行(文中122行)。至于这一行里面的操作,在后面介绍MessageQueue的时候将会介绍。而对于我们平常的主线程如果阻塞在这儿,不就啥事儿都干不了了?事实上,我们每一个UI操作、事件处理等操作也是通过Looper消息机制传递的,所以不用担心会阻塞在这儿。而一旦我们从队列中获取到了消息,我们将会通过135行进行消息的分发,这样就回到了我们熟悉的流程了。
这里写图片描述

Looper讲解到此为止!

0 0
原创粉丝点击