Android中Handler和Message事件转发流程详解

之前其实我在别的博客中说过这个了,大家可以进行参考。

Android Handler消息发送,子线程发消息执行UI操作

Android防止Handler造成内存泄漏的方法

不过这里我要进行一下比较全面一些的总结,因为关于Hanlder和Message的配合真的是很多的。我们就从主子线程消息传递来展开说说。

主线程和分线程之间传递消息的步骤主要有4个。

1.在主线程中构造一个Handler对象,并启动分线程

这里关于分线程的启动我就不说了,因为根据实际情况的不同我们会有不同的子线程。同时,我们不会为了消息转发去创建子线程,往往是因为子线程要更新UI界面所以要消息转发。因此,当我们开发需要消息转发时,我默认为你已经有一个子线程了,可能是因为要耗时操作启动的子线程,也可能是网络请求回调回来在子线程中。

我们说一下关于Handler对象的创建,其实很简单,我们可以直接创建一个对象

就像这样

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

 也可以创建一个内部类继承Handler,就像这样

    private class MineHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }

不管哪种,都实现了我们创建Handler的目的。之前我有一篇讲Hander的提过一种防止内存泄漏的Hander。之所以Handler会造成内存泄漏,是因为咱们Handler中的代码执行是依托消息的,也就是Handler本身有一堆代码,根据接收到的消息排队执行对应的代码。但是如果我们的引用没有了 ,比如Activity销毁了,但是Handler是不知道的,它还在执行,所以当用到了上下文的引用,就会产生内存泄漏的问题。 其实一方面可以使用我当时写的那种方法,把上下文引用存入WeakReference中,或者直接在引用的时候判断是否为空我认为也是可以的。

2.在分线程中构造一个Message对象的消息包。

当我们要从子线程转发消息到主线程时,就要构造一个Message对象。我一般就比较粗暴了,直接这样

Message message = new Message();

优雅一点的有这样 

Message message = Message.obtain();

 更优雅一点还可以这样

Message message = handler.obtainMessage();

总之作用是一样的,我们就是要创建一个Message对象。大家认识各种方法就好,万一小伙伴有这么写的认识就行。自己写的时候用自己习惯的。我就比较喜欢粗暴一些的。 

接着说说Message类的主要参数。

我们Message可以通过如下参数携带一些信息。

  • what:整型的消息标识,用于标识本次消息的唯一编号。
  • arg1:整型数,可存放消息的处理结果。
  • arg2:整型数,可存放消息的处理代码。
  • obj:Object类型,可存放返回消息的数据结构。
  • replyTo:Messenger类型,回应信使,在跨进程通信中使用,多线程通信用不着。

3.在分线程中通过Handler对象将Message消息发出去

处理器Handler的消息发送操作主要是各类send方法。下面总结一下(注意:Handler不是只有send类方法,还有很多别的方法,只是咱们这里只说和消息有关的)

  • obtainMessage:获取当前消息的对象。
  • sendMessage:立即发送消息。
  • sendMessageDelayed:延迟一段时间后发送消息。
  • sendMessageAtTime:在指定时间点发送消息。
  • sendEmptyMessage:立即发送空消息。
  • sendEmptyMessageDelayed:延迟一段时间后发送空消息。
  • sendEmptyMessageAtTime:在指定时间发送空消息。
  • removeMessages:从消息队列中根据指定标识移除对应的消息。
  • hasMessage:判断消息队列中是否存在指定标识的消息。

4.主线程中的Handler对象处理接收到的消息

主线程处理分线程发出的消息需要实现Handler对象的handleMessage方法,根据Message消息的具体内容分别进行相应处理。注意,因为handleMessage方法处于主线程(UI线程)中,所以该方法内部可以直接操作界面元素。

你可能感兴趣的:(Android,Studio开发实战,从零基础到APP上线)