基础篇
Handler的使用一般会先创建内部类继承Handler,重写handleMessage()方法。然后通过Handler对象发送消息。
中级篇
Handler源代码位于下面的路径,一共810行。
Frameworks/base/core/java/android/os/Handler.java 810行
Handler用来发送和处理消息。
Handler的构造方法,方法一是使用当前线程的Looper,方法二是使用开发者传入的Looper(一般情况是其它线程的Looper)。另外还有5个重载方法,最后到会调用到这两个方法。
Handler的成员变量,消息队列是通过Looper取得。
Handler发送消息,可以通过post()方法传入Runnable对象或者通过send()方法传入Message对象。Post()系列有5个方法,都会通过getPostMessage()方法把Runnable转换成Message,然后调用send()方法。
代码很清晰,最后会调用到MessageQueue的enqueueMessage()方法。中间过程主要就是构建Message对象。
移除消息也是通过Handler。都会调用到Messagequeue里面的移除方法。
判断是否有某条消息。都会调用到MessageQueue里面的方法,检索消息链表。
获取一个消息对象。都会通关过调用Message的obtainMessage()方法,从消息池获取一个Message对象。
处理消息。从前面的文章中知道Looper的loop()方法从消息队列取得消息后,就会调用Handler的dispatchMessage()方法。
代码很少,逻辑也很简单,就是一个优先级的关系。如果这个消息有回掉方法,优先调用消息的方法。然后是Handler的回掉方法。最后才是我们创建Handler重写的handleMessage()方法。
内存泄漏
在使用Handler的时候,可能会造成内存泄漏。泄露的原因是:非静态内部类持有外部类的引用。
Handler导致Activity泄露的原因:handler发送的消息在当前handler的消息队列中,如果此时activity finish掉了,那么消息队列的消息依旧会由handler进行处理,若此时handler声明为内部类(非静态内部类),我们知道内部类天然持有外部类的实例引用,这样在GC垃圾回收机制进行回收时发现这个Activity居然还有其他引用存在,因而就不会去回收这个Activity,进而导致activity泄露。
runWithScissors()
Handler提供runWithScissors()方法可同步等待消息处理完成。使用了内部类BlockingRunnable。用于线程同步。
HandlerThread/LooperThread
子线程中使用Handler消息机制,需要自行开启Looper循环,即在Thread的run()方法调用Looper的prepare()和loop()方法,然后创建Handler,就可以使用Handler消息机制。