笔记:学习 Android -Handler,Thread,Looper

来源:互联网 发布:排名算法 编辑:程序博客网 时间:2024/05/16 11:08

宏观思想:

Android系统有一套,不同线程间的消息处理机制。

这套消息处理机制由Handler, Meassage, Looper这三个Class组成,还有一个就是Message Queue,但它与Looper是一体。

简单来说,若想从一个线程传资料到另一个线程,你就需要用到以上三个class。

各自介绍

Handler:

摘自官方API
“A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue.”
Handler 是一个消息处理者,可以使用他发送消息,而他的Object会连结一个Thread。
怎样连结?
很简单,你在哪个Thread new出一个Handler object来,那麽这个Handler Object就自动绑定这个Thread,另外亦可透过Handler(Looper looper)这个Constructors去绑定相应的Thread。
一个线程可以绑定多个Handler!

Looper:

摘自官方API
“Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.”
Looper 当中就封装了message Queue,他就是管理这个Message Queue的人。

什麽是Message Queue?
人如其名,消息队列。存放Message object的地方,可想像为一个list。每个MessageObject都整整齐齐的排着队。

一个Thread只能有一个Looper,而且一开始,Thread本身不会绑定一个Looper的。
如果线程想与其他线程进行消息互联,那就一定要绑定一个Looper。

通常格式如下:
重点是要有Looper.prepare()和Looper.loop().

mHandler会自动会绑定在LooperThread.

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

所以,如果日後看到以上这个格式的代码,那就证明这个Thread已具备处理外来消息的条件。

为什麽一定要有个looper?
这是为了日後着想。
因为这个LooperThread不单只能处理1个消息,还能同时处理n个从其他Thread发过来的消息。
有了Looper,到来的消息都能排好队,然後交给LooperThread绑定好的Handler慢慢处理。

Message

摘自官方API
Defines a message containing a description and arbitrary data object that can be sent to a Handler. This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases.
While the constructor of Message is public, the best way to get one of these is to call Message.obtain() or one of the Handler.obtainMessage() methods, which will pull them from a pool of recycled objects.

专为消息处理机制而设。
1个Message Object可以带上一个任意Object,3个int 值,arg1,arg2,what。
Message不能主动new出来,要用Message.obtain()和handler.obtainMessage()来得出一个Message object。
用Message.obtain()会比较方便,static method,不用创一个object.

为什麽不能new?
可能是为节省资源。用以上两个方法,是从Android系统内废弃区(可循环再用的资源池,相信是类似缓冲区)拿出一些资源。

运作流程:

**注意:Main Thread预设就有Looper绑定好了,所以不需要进行什麽Looper绑定
MyHandler Object的引用,需要是全局变量。**

工作模式一:Worker Thread发消息给 Main Thread

1.在MainThread extends一个自定义的Handler class,并new一个object,同时重写他的handlerMeassage()方法。这样,MyHandler就会跟MainThread绑定,实际上是跟MainThread的Looper绑定(可叁考[1])。

2.在WorkerThread,用MyHandler Object的引用,调用sendMeassage()方法去发送资料。

3.因为MyHandler已经跟MainThread绑定了,所以这个Message会送去MainThread的Looper里的Message Queue。

4.当Looper 处理到 MyHandler的Message时,就会发给 MyHandler去处理。实际上是调用MyHandler里的handleMeassage方法。
这里写图片描述

工作模式二:MainThread发消息给WorkerTHread

流程跟模式一相似,只不过是绑定WorkerThread,和在WorkerThread创建Looper。

其实,当在workerThread new 一个Handler object的时候该Thread就一定要有Looper,不然会总译错误。

有Handler,就有Looper,缺一不可。
这里写图片描述

总结:

-若想从一个线程传资料到另一个线程就需要用到Handler, Meassage, Looper
-一个线程可以绑定多个Handler
-一个Thread只能有一个Looper,而且一开始,Thread本身不会绑定一个Looper
-有Handler,就有Looper,缺一不可。

叁老资料:
[1]很好的叁考资料,有代码解释,又有API source code进行讲解
http://cthhqu.blog.51cto.com/7598297/1283673

[2]图文详解。非常好。
http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html

[3]透彻的详细评解。
http://blog.csdn.net/bboyfeiyu/article/details/38555547

0 0
原创粉丝点击