Handler的标准使用步骤:
1、Looper.prepare();
2、Handler mHandler = new Handler(){
handleMessage(Message msg){}
};
3、Looper.loop();
小结: 一个looper对应一个消息队列MessageQueue和一个线程;
Looper:(负责轮训消息队列)
Looper.prepare()方法中做了三件事情:1、先通过ThreadLocal获取looper对应的线程是否为空,不为空就抛出异常,因为一个Looper只能对应一个线程,重复调用就表示把Looper设置给了多个线程,这是不被允许的(所以prepare()方法也只能调用一次);2、new一个Looper对象,通过ThreadLocal保存这个Looper对象(这个操作可以使不同线程中的数据副本互不影响);3、将Looper的变量mThread赋值为当前线程mThread = Thread.currentThread();
MessageQueue:(负责保存消息)
1、消息的入队:(handler中入队)
handler中发送消息的方法有以下几种:post(Runnable); postAtTime(Runnable,Obect,long);postAtTime(Runnable,long);
postDelayed(Runnable,long);这几个方法本质都是调用的sendMessageAtTime(Message,long);
在sendMessageAtTime(Message,long);方法中,1、先拿到mQueue(handler的一个属性)赋值给Message的queue属性,mQueue是在handler的构造方法中通过Looper的消息队列赋值的(也印证上面的一个Looper对应一个MessageQueue的说法);2、调用enqueueMessage(queue, msg,long);进行消息的入队,在这个方法中,给msg.target赋值this(当前类是Handler),标明这个消息是属于哪个handler的,再调用enqueue.enqueueMessage()入队;
2、消息的出队:(Looper中出队)
loop()方法:先通过ThreadLocal获取到当前线程对应的Looper,再从Looper中拿到存放的消息队列(入队的时候都赋值了),然后开启死循环通过next()方法从消息队列中拿到一个个消息,如果没有消息则进入阻塞状态,有消息则通过msg.target.dispatchMessage(msg)方法进行消息的分发回调(msg.target在入队的时候赋值的就是handler)
3、消息的处理:(handler中处理)
dispatchMessage(Message):先判断消息msg的callback回调是否为空,postRunnable()方法中将runnable封装成了msg的callback;然后判断handler本身的callback是否为空(在handler的构造方法中设置了);如果前两个都没有执行,最后调用handleMessage()方法,这个方法是由子类重写去实现消息的处理;
Handler:(负责发送消息和处理消息)