欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android消息机制Handler用法总结

程序员文章站 2022-07-03 19:37:06
1.简述handler消息机制主要包括: messagequeue、 handler、 looper、message。 message:需要传递的消息,可以传递数据; messageque...

1.简述

handler消息机制主要包括: messagequeue、 handler、 looper、message。

  • message:需要传递的消息,可以传递数据;
  • messagequeue:消息队列,但是它的内部实现并不是用的队列,而是通过单链表的数据结构来维护消息列表,因为单链表在插入和删除上比较有优势。主要功能是向消息池投递消息( messagequeue.enqueuemessage)和取走消息池的消息( messagequeue.next)。 
  • handler:消息辅助类,主要功能是向消息池发送各种消息事件( handler.sendmessage)和处理相应消息事件( handler.handlemessage); 
  • looper:消息控制器,不断循环执行( looper.loop),从messagequeue中读取消息,按分发机制将消息分发给目标处理者。

2.异步线程切换原理

class looperthread extends thread {
      public handler mhandler;
 
      public void run() {
          looper.prepare();
 
          mhandler = new handler() {
              public void handlemessage(message msg) {
                  // process incoming messages here
              }
          };
 
          looper.loop();
      }
  }

每一个异步线程,都维护着唯一的一个looper,每一个looper会初始化(维护)一个messagequeue,之后进入一个无限循环一直在读取messagequeue中存储的消息,如果没有消息那就一直阻塞等待。

我们在实例化handler的过程中,会先得到当前所在线程的looper对象,之后得到与该looper对象相对应的消息队列,看源码handler中持有looper、messagequeue。

    private static void handlecallback(message message) {
        message.callback.run();
    }
 
    final looper mlooper;
    final messagequeue mqueue;
    final callback mcallback;

当我们发送消息的时候,即handler.sendmessage或者handler.post,会将msg中的target赋值为handler自身,这就是实现message从一个线程到另外一个线程的传递的本质,之后加入到消息队列中。

private boolean enqueuemessage(messagequeue queue, message msg, long uptimemillis) {
    msg.target = this;
    if (masynchronous) {
        msg.setasynchronous(true);
    }
    return queue.enqueuemessage(msg, uptimemillis);
}

我们一般会重写handlermessage方法处理消息,这将会在msg.target.dispatchmessage方法中被回调,从而实现了message从一个线程到另外一个线程的传递。

3.总结

  • 1.handler 的背后有 looper、messagequeue 支撑,looper 负责消息分发,messagequeue 负责消息管理;
  • 2.在创建 handler 之前一定需要先创建 looper,looper 有退出的功能,但是主线程的 looper 不允许退出;
  • 3.异步线程looper,looper.prepare()创建looper,looper.loop()开始轮询,需要自己调用 looper.mylooper().quit()退出;
  • 4.runnable 被封装进了 message,可以说是一个特殊的 message;
  • 5.handler.handlemessage() 所在的线程是 looper.loop() 方法被调用的线程;
  • 6.handler内存泄漏的原因

原因:messagequeue持有message,message持有activity,delay多久,message就会持有activity多久。

解决方案:静态内部类、弱引用,最后不要忘记调用handler.removecallbacksandmessages(null)清空所有消息。

public class sampleactivity extends activity {
 
  /**
   * instances of static inner classes do not hold an implicit
   * reference to their outer class.
   */
  private static class myhandler extends handler {
    private final weakreference<sampleactivity> mactivity;
 
    public myhandler(sampleactivity activity) {
      mactivity = new weakreference<sampleactivity>(activity);
    }
 
    @override
    public void handlemessage(message msg) {
      sampleactivity activity = mactivity.get();
      if (activity != null) {
        // ...
      }
    }
  }
 
 // myhandler
 private final myhandler mhandler = new myhandler(this);
 
  /**
   * instances of anonymous classes do not hold an implicit
   * reference to their outer class when they are "static".
   */
  private static final runnable srunnable = new runnable() {
      @override
      public void run() { /* ... */ }
  };
 
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
 
    // post a message and delay its execution for 10 minutes.
    mhandler.postdelayed(srunnable, 1000 * 60 * 10);
    
    // go back to the previous activity.
    finish();
  }
 
  @override
  protected void ondestroy() {
        super.ondestroy();
        //mhandler.removecallbacksandmessages(null);
    }
}

以上所述是小编给大家介绍的android消息机制handler用法总结,希望对大家有所帮助。在此也非常感谢大家对网站的支持!