Android Handler机制

这篇具有很好参考价值的文章主要介绍了Android Handler机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android Handler机制

Android Handler 机制是一种用于在 Android 应用中处理多线程和异步操作的机制。

设计特点

为了解决UI线程(主线程)和后台线程之间的通信和异步处理的问题。在Android应用中,特别是在UI开发中,有一些重要的原则需要遵循:

  1. 主线程负责UI更新: Android UI框架是单线程模型的,也就是说UI更新必须在主线程上进行。如果在主线程上执行耗时操作,会导致界面卡顿、失去响应等用户体验问题。

  2. 异步处理耗时操作: 为了避免在主线程上执行耗时操作,需要在后台线程上执行这些操作。但是,后台线程不能直接更新UI,因此需要一种机制来在后台线程执行任务后通知主线程更新UI。

为了解决这些问题,Android引入了Looper、Handler、MessageQueue和Message:

  • Looper: 负责创建一个消息队列,循环处理消息。

  • MessageQueue: 用于存储消息,按照一定规则将消息分发给Handler。

  • Handler: 用于发送和处理消息,通过与Looper关联,使得处理消息的操作在特定线程(通常是主线程)执行。

  • Message: 包含要处理的数据和操作的对象,通过Handler发送到MessageQueue中。

这个设计模型允许在主线程和后台线程之间进行有效的通信和任务分发,使得应用能够更好地响应用户输入、保持界面流畅。

简单的示例

下面是一个简单的示例,演示了如何使用 Handler 在后台线程中执行任务并在主线程中更新 UI:

public class ExampleActivity extends AppCompatActivity {
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_example);

        // 创建 Handler 对象,并关联主线程的 Looper
        handler = new Handler(Looper.getMainLooper());

        // 启动后台线程执行任务
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 模拟耗时操作
                doBackgroundWork();

                // 在主线程中更新 UI
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateUI();
                    }
                });
            }
        }).start();
    }

    private void doBackgroundWork() {
        // 模拟耗时操作
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void updateUI() {
        // 在主线程中更新 UI
        TextView textView = findViewById(R.id.textView);
        textView.setText("Task completed!");
    }
}

在上述示例中,通过 Handler 将 updateUI() 方法安排到主线程执行,以确保在更新 UI 时不会出现线程问题。这样可以避免在后台线程中直接更新 UI,从而确保在主线程中执行 UI 操作。

 Handler 机制的核心组成部分

Android Handler机制,Android知识总结,android

1. Handler:

Handler 是 Android 中的一个类,用于发送和处理消息以及运行代码块。主要功能包括:

  • 发送消息到消息队列。

  • 处理消息队列中的消息,执行相应的操作。

  • 安排代码块在指定的时间之后运行。

  • Handler 包含一个 Looper 对象

+-------------------------+
|       Handler           |
+-------------------------+
| - mLooper: Looper       |
| - mCallback: Callback   |
+-------------------------+
| + handleMessage(msg: Message): void |
| + dispatchMessage(msg: Message): void |
| + sendMessage(msg: Message): boolean |
| + post(runnable: Runnable): boolean |
+-------------------------+

2. Looper:

  • Looper 与每个线程关联,负责管理该线程的消息队列。

  • 包含一个 MessageQueue 对象,它负责管理线程的消息队列。

  • 通过 Looper.getMainLooper() 可以获取主线程的 Looper,在其他线程中可能需要显式创建。

  • 在主线程中,Looper 默认是启动的,因此可以直接使用 Handler

+-------------------------+
|        Looper           |
+-------------------------+
| - mQueue: MessageQueue  |
| - mThread: Thread       |
+-------------------------+
| + prepare(): void       |
| + loop(): void          |
| + myLooper(): Looper    |
| + getMainLooper(): Looper|
+-------------------------+

默认情况下当我们创建一个新的线程的时候,这个线程里面是没有消息队列MessageQueue的。为了能够让线程能够绑定一个消息队列,我们需要借助于Looper:首先我们要调用Looper的prepare方法,然后调用Looper的loop方法。

prepare()方法
public static final void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(true));

sThreadLocal是一个ThreadLocal对象,可以在一个线程中存储变量。可以看到,将一个Looper的实例放入了ThreadLocal,并且先判断了sThreadLocal.get是否为null,否则抛出异常。这也就说明了Looper.prepare()方法不能被调用两次,同时也保证了一个线程中只有一个Looper实例。

loop()方法
    public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;
        ......
        for (;;) {
            Message msg = queue.next();
            if (msg == null) {
                // 如果Message链表的头结点为空,说明没有消息可执行,此次loop停止
                return;
            }
            ......
            try {
                // 执行消息承载的方法
                msg.target.dispatchMessage(msg);
                end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            ......
            msg.recycleUnchecked();
        }
    }

msg.target.dispatchMessage(msg);

msg的target属性是Handler,每个msg包含一个handler对象,该代码的意思是让Message所关联的Handler通过dispatchMessage方法让Handler处理该Message。

Looper主要作用

1.与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。

2.loop()方法,不断从MessageQueue中去取消息,交给消息Message的target属性,即Handler的dispatchMessage去处理。

3. MessageQueue:

MessageQueue 包含 Message 对象。

MessageQueue 是消息队列的实现。它按照消息的时间戳(先进先出)的顺序存储消息。

+-------------------------+
|     MessageQueue        |
+-------------------------+
| - mMessages: Message    |
+-------------------------+
| + enqueueMessage(msg: Message, when: long): void |
| + next(): Message       |
| + removeMessages(what: int, obj: Any): void       |
+-------------------------+

 4. Message:

Message 是一个包含要处理的数据和操作的对象。Handler 通过 sendMessage() 方法发送消息到消息队列,然后由 Looper 传递给相应的 Handler 进行处理。

+-------------------------+
|        Message          |
+-------------------------+
| - what: int             |
| - obj: Object           |
| - target: Handler       |
| - when: long            |
+-------------------------+
| + obtain(): Message     |
| + recycle(): void       |
+-------------------------+

5. Runnable 和 Message 处理:

Handler 可以处理两种类型的任务:通过 post() 方法安排的 Runnable 对象,以及通过 sendMessage() 发送的 Message 对象。

总结

  • Handler 包含一个 Looper 对象,Looper 包含一个 MessageQueue 对象,MessageQueue 包含 Message 对象。

  • Handler 可以发送 Message 到 MessageQueue 中,Looper 会循环处理 MessageQueue 中的消息,调用相关联的 Handler 的 handleMessage 方法。

  • Looper主要作用

    1.与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。

    2.loop()方法,不断从MessageQueue中去取消息,交给消息Message的target属性,即Handler的dispatchMessage去处理。

  • Message 中包含了要处理的数据和操作,可以通过 Handler 的 sendMessage() 方法发送到消息队列。

关于更详细的源码讲解可参考(特别感谢):

Android 中为什么需要 Handler? - 知乎

Android Handler机制-Looper、Handler、MessageQueue、Message的关系 - 掘金

Android应用程序消息处理机制(Looper、Handler)分析_罗升阳 handler-CSDN博客文章来源地址https://www.toymoban.com/news/detail-825989.html

到了这里,关于Android Handler机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Handler原理机制解析,Android开发中的重要性

    Handler在android程序开发中使用的非常频繁、我们知道android是不允许在子线程中更新UI的,这就需要借助Handler来实现,那么你是否想过为什么一定要这个这样子做呢?而且Handler的内部消息处理机制究竟是什么样的呢?Handler的原理是需要通过源代码才能说的清楚的,而且它处理

    2024年02月06日
    浏览(41)
  • Android源码解析--享元设计模式,handler消息传递机制(基于Android API 33 SDK分析)

    使用共享对象可有效地支持大量的细粒度的对象 核心:对象复用。 1.1 享元模式Demo 火车票购票Demo 缓存对象在一个Map中。下面我们还会分析 用法 跟进去 这就是最明显的一个享元设计模式。 Android 开发一个知识点:UI 不能够在子线程中更新。 我们跟进post函数 Handler 传递了一个

    2024年02月11日
    浏览(35)
  • 【Android】多线程编程、异步消息处理机制以及new Handler()被标记为过时的解决办法,解决Handler内存泄漏问题和AsyncTask的基本用法

    1.1 弱引用 WeakReference (弱引用)是一种在Java中用于管理对象的引用的特殊引用类型。它的作用是在垃圾回收过程中,允许对象在没有强引用指向它时被回收( 当一个对象只有弱引用指向它,而没有强引用指向它时,垃圾回收器可能会在下一次垃圾回收时回收该对象,即使系

    2024年02月04日
    浏览(49)
  • Android:Handler

    参考来源 参考来源 参考来源 参考来源 Binder/Socket用于进程间通信,而Handler消息机制用于同进程的线程间通信 handler机制是android系统运行的基础,它采用生产者,消费者模式进行设计。其中生产者和消费者都是handler,多个handler会生产消息message投递到线程共享的messagequeue有序

    2024年02月02日
    浏览(35)
  • Android handler用法及分析

    这里将handler机制中的message,looper和messagequeue分开分析,分开了解之后,会在进行一个总结。先来看handler里面都有哪些方法都做了哪些事情, hide方法和带有@UnsupportedAppUsage注释的方法(此方法不对外暴露使用)暂不描述 。 handler要传递的callback接口在handler类里面,该接口里面

    2024年02月05日
    浏览(47)
  • Android学习之路(13) Handler详解

    Handler是一套 Android 消息传递机制,主要用于线程间通信。 用最简单的话描述: handler其实就是主线程在起了一个子线程,子线程运行并生成Message,Looper获取message并传递给Handler,Handler逐个获取子线程中的Message. Binder/Socket用于进程间通信,而Handler消息机制用于同进程的线程间

    2024年02月09日
    浏览(42)
  • Android Handler被弃用,那么以后怎么使用Handler,或者类似的功能

    Android API30左右,Android应用在使用传统写法使用Handler类的时候会显示删除线,并提示相关的方法已经被弃用,不建议使用。 Android studio中的显示和建议: 看下官方API关于此处的解释:  简要说就是如果在实例化Handler的时候不提供Looper, 可能导致操作丢失(Handler 没有预估到新

    2023年04月21日
    浏览(44)
  • Android中正确使用Handler的姿势

    在Android中,Handler是一种用于在不同线程之间传递消息和任务的机制。以下是在Android中正确使用Handler的一些姿势: 1. 在主线程中创建Handler对象 在Android中,只有主线程(也称为UI线程)可以更新UI。因此,如果您需要在后台线程中执行某些任务并更新UI,则需要使用Handler将任

    2024年02月11日
    浏览(47)
  • Android中线程间的通信-Handler

    Handler机制在Android中主要用于线程间的通信,特别是处理从子线程向主线程(UI线程)传递消息和更新界面。 Message : Message  是在线程间传递的数据载体,它包含了需要处理的数据和一些额外的信息。 每个  Message  对象可以携带一个  what  值(整数类型),用于标识消息的

    2024年02月03日
    浏览(34)
  • 带你深入了解Android Handler的用法

    Android中,Handler是一类用于异步消息传递和线程之间通信的基础框架。一个Handler是一个线程的处理器,可以接收消息,并调度运行它们。使用Handler,应用程序可以将处理器与一个线程关联,以将来的时间运行任务。而使用Handler,就可以避免启动额外的线程,从而提高代码的

    2024年02月07日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包