Android消息机制Handler用法总结

作者:天若子 时间:2022-08-10 23:58:56 

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用法总结网站的支持!

来源:https://blog.csdn.net/zhukui66/article/details/121505150

标签:Android,Handler,消息机制
0
投稿

猜你喜欢

  • Android中View跟随手指移动效果

    2021-07-26 00:21:18
  • Java工程中使用Mybatis (工程结合Mybatis,数据结合Swing使用))

    2023-05-27 11:52:38
  • 一文详解Java线程的6种状态与生命周期

    2022-02-08 08:44:30
  • Java JDK11基于嵌套的访问控制的实现

    2021-07-11 10:02:05
  • RocketMQ-延迟消息的处理流程介绍

    2023-07-28 01:58:59
  • java项目中的绝对路径和相对路径用法说明

    2023-11-27 22:08:44
  • Android下Activity全屏显示实现方法

    2022-12-17 19:57:56
  • java中断线程的正确姿势完整示例

    2023-01-27 06:33:58
  • java8学习教程之函数引用的使用方法

    2023-08-28 12:03:19
  • SpringBoot项目打jar包与war包的详细步骤

    2022-01-12 01:28:21
  • java接口自动化测试框架及断言详解

    2022-01-23 20:01:36
  • C#窗体实现酒店管理系统

    2023-05-23 18:58:47
  • java中JVM中如何存取数据和相关信息详解

    2023-08-10 03:49:46
  • C#中反射和扩展方法如何运用

    2023-08-02 01:43:16
  • SpringCloud超详细讲解负载均衡组件Ribbon源码

    2021-06-17 18:39:47
  • C#(asp.net)多线程用法示例(可用于同时处理多个任务)

    2022-03-09 01:41:30
  • springboot开启声明式事务的方法

    2021-06-18 23:50:48
  • 为SpringBoot服务添加HTTPS证书的方法

    2023-10-11 03:03:22
  • Java中双大括号初始化的理解与使用

    2023-08-30 08:44:55
  • Android实现关机后数据不会丢失问题

    2021-06-08 18:54:47
  • asp之家 软件编程 m.aspxhome.com