Handler 详讲

版权声明:转发请标明原著 https://blog.csdn.net/weixin_39460667/article/details/83240376

前置知识:ThreadLocal     不懂请进入 一> ThreadLocal

                   强、虚、软,弱   一>    传送门

执行流程

handler、looper、queue 的 联系 先看图片

 主线程(即UI线程)自身就有message loop,不需要创建,ActivityThread 作为 Android的程序启动入口,他为我们自动创建了一个looper,然后在使用looper.loop( ); 这个是调用looper的循环器,不断取出消息。

其他线程就需要手动创建,使用prepare()创建loop,使用 loop()来启动loop,直到 loop 停止。

一个handler 对应有一个 queue(一个线程一个实例化handler),每一个 queue 对应有一个 looper,looper其归属于其创建的地方。

为了维护各个线程的 looper 能够 互相不干扰存储 和 修改数据,ThreadLocal 起到了至关重要的作用

扫描二维码关注公众号,回复: 3744429 查看本文章

下文的主线是根据handler的构造方法来进行的,先看如下一段代码

一、

    public Handler() {
        this(null, false);
    }

默认执行handlemessage,案例代码。

  Handler mhandler= new Handler(){
       @Override
       public void handleMessage(Message msg) {
           Log.e("handleMessage: ","hello world" );
           super.handleMessage(msg);
       }
   };

二、

    public Handler(Callback callback) {
        this(callback, false);
    }

 执行上图中的第二个方法。实现回调Callback接口的方法,案例代码。

三、

    public Handler(Looper looper) {
        this(looper, null, false);
    }

在子线程的创建的handle,此时并且拥有自己的 looper,queue,案例代码。

 private Handler myhandler;
    Thread mthread = new Thread(new Runnable() {
        @Override
        public void run() {
            Looper.prepare();
            myhandler = new Handler(Looper.myLooper());
            Looper.loop();
        }
    });

此后运用这个handler对象,来进行传递信息,就是存储在子线程中的queue当中。

这里也可以使用 HandlerThread 来使用,更加简洁 一> HandlerThread

四、

    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }

此处根据上面总结可得

六、

   public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

MessageQueue 

他的数据结构是使用单链表来合成的 ,插入,删除也都是一样的。enqueueMessage()方法。

handler.sendMessage(msg) vs handler.post(runnable)

post(r)方法调用了sendMessageDelay(msg),将runnable任务包装成了msg的Callback属性

handle.dispatchMessage()首先判断msg的Callback是否为空

若不为空,则执行run()方法,否则才执行handleMessage()方法

其实通过 post 方法传递过来的 Runable 方法,也是把它转化成Callback 类型,从而也跟sendMessage执行相同的操作。

post(Ruunable r)

public final boolean post(Runnable r)
{
   return  sendMessageDelayed(getPostMessage(r), 0);
}

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

避免出现内存泄漏

将 Handler 声明为静态类,并持有一个对 Activity 的弱引用。

static class MyHandler extends Handler {
    WeakReference<Activity > mActivityReference;

    MyHandler(Activity activity) {
        mActivityReference= new WeakReference<Activity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        final Activity activity = mActivityReference.get();
        if (activity != null) {
            mImageView.setImageBitmap(mBitmap);
        }
    }
}

若泄漏是因为 Handler 被 delay 的 Message 持有了引用,可在 Activity 的 onDestroy() 中执行 mHandler.removeCallbacks() 方法

下面两篇文章的源码写得挺好的,有空大家可以看一看        

源码https://www.jianshu.com/p/b03d46809c4d

           https://www.jianshu.com/p/0a274564a4b1

猜你喜欢

转载自blog.csdn.net/weixin_39460667/article/details/83240376