Handle

让我来解释 Handler 的核心概念:

为什么需要 Handler?

Android 规定只能在主线程(UI线程)更新UI

但耗时操作(如网络请求、文件IO)不能在主线程执行

需要一个机制在子线程和主线程之间传递消息,这就是 Handler 的主要作用

Handler 的核心组件:

Handler:消息的发送和处理者

Message:消息对象,包含要传递的信息

MessageQueue:消息队列,用于存储消息

Looper:消息循环器,不断从 MessageQueue 中取出消息并交给 Handler 处理

工作流程:

Looper 通过 ThreadLocal 确保每个线程最多只有一个 Looper 实例

主线程(UI线程)默认已经创建了 Looper,子线程需要手动创建

Handler 发送消息(Message)到 MessageQueue

Looper 不断循环从 MessageQueue 取出消息,分发给对应的 Handler 处理

与后端开发的对比:

类似于生产者-消费者模式

Handler 类似于消息的生产者和消费者

MessageQueue 类似于消息队列(如 RabbitMQ)

Looper 类似于消息队列的消费者监听器

我已经在代码示例中展示了 Handler 的基本使用方式和内部原理。您可以看到:

如何创建 Handler 并处理消息

如何在子线程中发送消息

Looper 的实现原理

MessageQueue 的消息管理机制

这种设计的优点是:

实现了线程间的安全通信

避免了线程同步的复杂性

统一了异步任务的处理方式

java 复制代码
// 1. Handler 的基本使用
public class MainActivity extends Activity {
    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_UI:
                    // 在主线程更新UI
                    textView.setText("更新UI");
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 在子线程执行耗时操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 模拟网络请求
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                // 通过Handler发送消息到主线程
                Message msg = Message.obtain();
                msg.what = MSG_UPDATE_UI;
                mHandler.sendMessage(msg);
                
                // 或者使用post方法
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        // 这个代码块会在主线程执行
                        textView.setText("更新UI");
                    }
                });
            }
        }).start();
    }
}

// 2. Handler 内部原理示意
public class Looper {
    // 每个线程只能有一个Looper
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    final MessageQueue mQueue;  // 消息队列
    
    private Looper() {
        mQueue = new MessageQueue();
    }
    
    // 为当前线程创建Looper
    public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }
    
    // 开启消息循环
    public static void loop() {
        final Looper me = myLooper();
        final MessageQueue queue = me.mQueue;
        
        for (;;) {
            Message msg = queue.next(); // 可能会阻塞
            if (msg == null) {
                return;
            }
            // 分发消息到对应的Handler
            msg.target.dispatchMessage(msg);
        }
    }
}

// 3. 消息队列示意
public class MessageQueue {
    Message mMessages;  // 消息链表的头部
    
    // 取出一条消息
    Message next() {
        for (;;) {
            synchronized (this) {
                // 取出消息链表中的第一条消息
                Message msg = mMessages;
                if (msg != null) {
                    mMessages = msg.next;
                    return msg;
                }
                // 如果没有消息,就等待
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
    }
    
    // 插入一条消息
    boolean enqueueMessage(Message msg, long when) {
        synchronized (this) {
            msg.when = when;
            Message p = mMessages;
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;
                mMessages = msg;
            } else {
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                }
                msg.next = p;
                prev.next = msg;
            }
            notify();  // 唤醒等待的线程
        }
        return true;
    }
}
相关推荐
Devil枫1 小时前
Kotlin高级特性深度解析
android·开发语言·kotlin
ChinaDragonDreamer1 小时前
Kotlin:2.1.20 的新特性
android·开发语言·kotlin
雨白12 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹13 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空15 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭16 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日17 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安17 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑17 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟21 小时前
CTF Web的数组巧用
android