Android

多线程—Handler

2019-12-27  本文已影响0人  似焰如火

1 说在头里

之前看到一段话,感觉很有用,这里引用一下。

Handler并不是专门用来更新UI的,只是开发者常常用它来更新UI。Handler的主要用于同一个进程间的线程通信,Handler用于更新UI的时候是"子线程与主线程通信";当然,Handler也可以用于子线程之间通信。Handler的消息机制主要是就指“Handler的运行机制”,Handler的运行机制时需要底层的MessageQueue和Looper支持的。
改短摘自链接:https://www.jianshu.com/p/f1da1ed7bd7e

2 Handler的使用

还是先说说这个东西咋用吧,分三步走,上栗子。

  1. 在主线程创建handler,重写handleMessage方法
private  Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int arg1=msg.arg1;
            if (msg.what==0x1234){
                textView.setText(arg1);
            }
        }
    };
  1. 在子线程中使用handler对象发送消息
         Message message=handler.obtainMessage();
         message.what=0x1234;
         message.arg1=10086;
         handler.sendMessage(message);
  1. 主线程中handler捕获消息,回调handleMessage对其进行处理

说到Handler,肯定是离不开Looper、MessageQueue、Message的。这几位大哥之间的关系很是亲密,下面有必要八卦一下。

3 Looper、MessageQueue、Message

先说说Looper,每一个线程最多只能有一个Looper。主线程中ActivityThread默认会把Looper初始化好,无需我们再建。但如果想要在子线程中创建一个Handler,那就要我们提前手工制作一个Looper了。制作方法很简单,只需调用静态方法prepare()即可

Looper.prepare();
Handler handler = new Handler() {
// 我懒了....
}
Looper.loop();

它的特点是它跟它的线程是绑定的,处理消息也是在Looper所在的线程去处理,所以当我们在主线程创建Handler时,它就会跟主线程唯一的Looper绑定,从而我们使用Handler在子线程发消息时,最终也是在主线程处理,达到了异步的效果。
来自 https://www.cnblogs.com/ryanleee/p/8204450.html

线程在初始化Looper时,会自动创建一个MessageQueue对象。

MessageQueue是一个消息队列,用来存放Handler发送的消息。MessageQueue通常都是由Looper来管理,MessageQueue大哥是跟着Looper大哥大混饭的,Looper上了,不用招呼MessageQueue立马就上(Looper创建时,自动创建一个MessageQueue)。Looper维护MessageQueue消息队列,该消息队列用来存放Handler发送的Message

Message 消息对象,就是MessageQueue里面存放的对象。MessageQueue大哥可以收纳多个Message小弟。这个小弟的作用自然就是通风报信了(可以说是消息的载体),Handler会派出来一个Message,Message先到MessageQueue大哥处报道,Looper大哥大巡视时,提取Message问话。(Looper从MessageQueue中提取Message,并有Handlee的handleMessage()方法处理)

当我们需要发送一个Message时,我们一般不建议使用new Message()的形式来创建,更推荐使用Message.obtain()来获取Message实例,因为在Message类里面定义了一个消息池,当消息池里存在未使用的消息时,便返回,如果没有未使用的消息,则通过new的方式创建返回,所以使用Message.obtain()的方式来获取实例可以大大减少当有大量Message对象而产生的垃圾回收问题。
来自 https://www.cnblogs.com/ryanleee/p/8204450.html

4 Handler使用总结

Handler有两种方式去执行一些UI相关操作:

  1. 使用sendMessage()发送消息
    //定义MyHandler类,并重写handleMessage()方法
    class MyHandler extends Handler {
         @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //执行某些操作,可更新UI 
        }
    }
    //主线程中创建MyHandler的实例
    private MyHandler myhandler = new MyHandler();
    //在子线程中创建需要发送的消息对象,Hander发送消息到消息队列
    Message msg = Message.obtain();
    msg.what = 1;
    myhandler .sendMessage(msg);
  1. 使用Handler.post()方法
    //主线程中先创建Handler实例
    private Handler handler = new Handler();
    //在子线程中使用Handler.post()
     handler.post(new Runnable() {
                                @Override
                            public void run() {
                                 //可以执行一些UI相关操作 
                            }
                        });

可以看出,第二种方式比较灵活,无需定义Handler子类重写handleMessage()方法,只需要在子线程中使用主线程中创建的Handler对象,在子线程中调用Handler对象的post()方法即可。

上一篇下一篇

猜你喜欢

热点阅读