美文网首页
Handler Looper Message

Handler Looper Message

作者: hiLily | 来源:发表于2017-11-19 20:15 被阅读24次

    首先,他们仨是啥?先简单总结一下:

    1.Looper 

    负责在所给定线程里run起一个消息循环,往简单说它就弄了个死循环,不停在message queue里取消息,有消息就处理消息,没消息就阻塞

    这一切是在Loop.loop()实现的,注意,它是这个类的静态方法,简单看一下这个方法的实现,我摘取了重要的几行:

    public static Looper myLooper() {

    return sThreadLocal.get();//ThreadLocal类,对不同线程不同实例的类,这里对ThreadLocal类的应用也是Looper设计的精髓所在

    }

    public static void loop() {

    final Looper me = myLooper();//获取当前线程的Looper对象

    final MessageQueue queue = me.mQueue;

    for (;;) {//死循环

    Message msg = queue.next(); // might block阻塞在这里面实现

    if (msg == null) {

    // No message indicates that the message queue is quitting.

    return;

    }

    msg.target.dispatchMessage(msg);//target就是handler

    msg.recycleUnchecked();//回收Message对象,将属性归零,将此message对象作为链表头

    }

    }

    另一个重要的static方法,Looper.prepare(),其实就是为当前线程创建一个Looper对象

    private static void prepare(boolean quitAllowed) {

    if (sThreadLocal.get() != null) {

    throw new RuntimeException("Only one Looper may be created per thread");

    }

    sThreadLocal.set(new Looper(quitAllowed));

    }

    2.Message

    本质上是个链表,next对象指向message池中的第一个可用message,至于为啥要节约使用message对象,要弄个缓存池我没理解

    其中MessageQueue被Looper引用,当next方法被调用时,使用nativePollOnce实现无消息时的阻塞

    3.Handler

    起到分发和处理的作用,怎么知道哪个message给哪个handler处理呢?message里面的target属性,就是指向处理者Handler。其比较重要的几个方法:

    A.构造new Handler()会获取当前线程所在looper对象,那么就有个要求啦,必须是一个prepare过的Looper,因为如果不prepare过,那当前线程的looper对象是没有建立的,这点对于主线程来说,在ActivityThread中早就调用过Looper.prepareMainThread(),因此主线程可以随便new handler不会报错,但是在其他线程就不能这么任性了。

    B.sendMessage

    其实就是把message放到message queue里面

    C.obtainMessage

    调用了Message.obtain()方法,新建或重用一个message对象

    D.dispatchMessage & handleMessage

    Looper的loop方法中调用dispatchMessage

    一般都会重写handleMessage方法来处理收到的message,如果message自带callback那就用message自己的callback

    其次,为啥会有经典的内存泄漏问题呢?

    如果我们在Activity里面写个子类MyHandler extends Handler,这样呢就会遇到一个经典的内存泄漏问题啦

    因为java的内部类会持有对外部类的引用,而message对象的target又持有handler的引用,一旦我们发送一个延迟处理的消息,就会导致关闭Activity的时候无法回收Activity对象,从而造成泄漏啦。处理的方法,要么就写成一个静态内部类,让handler不要引用Activity,要么就在activity的onDestroy()方法里调用在activity的onDestroy()方法里调用handler.removeCallbacksAndMessages(null);把message神马的都清空,就没事了

    再次,HandlerThread是个什么鬼?

    其实它很简单,它从源码上看,和Handler没啥关系,就是一个带Looper的Thread,就这么简单,那为啥叫HandlerThread呢?因为Handler要用它的Looper啊,就这么简单的关系。

    它能干点啥呢?排队嘛,因为message是一个个的处理的,所以这个非常适合在work thread中需要一个个依序排队处理请求的情况。

    相关文章

      网友评论

          本文标题:Handler Looper Message

          本文链接:https://www.haomeiwen.com/subject/dlmuvxtx.html