Android Handler 机制完全解析

📱 一、Handler 是什么?

Handler 的核心作用

复制代码
// Handler 是 Android 中用于线程间通信的机制
// 主要解决:子线程更新 UI 的问题

为什么需要 Handler?

复制代码
// Android 主线程(UI线程)限制:
1. 只有主线程能更新 UI
2. 主线程不能执行耗时操作(会 ANR)
3. 子线程不能直接操作 UI(会崩溃)

// 解决方案:Handler
子线程 → Handler → 主线程
(发送消息)     (处理消息,更新 UI)

⚙️ 二、Handler 机制的四大组件

核心组件关系图

复制代码
┌─────────────────────────────────────────┐
│               MessageQueue               │
│    ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐     │
│    │ Msg │ │ Msg │ │ Msg │ │ Msg │     │
│    └─────┘ └─────┘ └─────┘ └─────┘     │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│                 Looper                   │
│  ┌─────────────┐    ┌─────────────┐    │
│  │ 无限循环     │───▶│ 取消息       │    │
│  │  loop()     │    │ next()      │    │
│  └─────────────┘    └─────────────┘    │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│                 Handler                  │
│                                         │
│  ┌──────────────────────────────┐      │
│  │      handleMessage()         │      │
│  │       处理消息,更新UI         │      │
│  └──────────────────────────────┘      │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│               Thread                    │
│         主线程/子线程                     │
└─────────────────────────────────────────┘

1. Message(消息)

复制代码
// Message.java - 消息对象
public final class Message implements Parcelable {
    public int what;          // 消息标识
    public int arg1;          // 整型参数1
    public int arg2;          // 整型参数2
    public Object obj;        // 任意对象参数
    public Bundle data;       // Bundle数据
    public Messenger replyTo; // 跨进程通信
    public Handler target;    // 目标Handler
    public Runnable callback; // Runnable回调
    
    // 消息池(复用机制,避免频繁创建对象)
    private static Message sPool;
    private static int sPoolSize = 0;
    private static final int MAX_POOL_SIZE = 50;
    
    // 获取消息(推荐使用,从消息池获取)
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }
    
    // 回收消息(回到消息池)
    public void recycle() {
        clearForRecycle();
        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }
}

2. MessageQueue(消息队列)

复制代码
// MessageQueue.java - 消息队列(单链表实现)
public final class MessageQueue {
    
    // 消息队列头
    private Message mMessages;
    
    // 插入消息
    boolean enqueueMessage(Message msg, long when) {
        synchronized (this) {
            msg.when = when;
            Message p = mMessages;
            
            // 1. 队列为空,或新消息执行时间最早
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;
                mMessages = msg;
                this.notify(); // 唤醒 Looper
            } 
            // 2. 插入到合适位置(按执行时间排序)
            else {
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                }
                msg.next = p;
                prev.next = msg;
            }
            return true;
        }
    }
    
    // 取出消息
    Message next() {
        for (;;) {
            synchronized (this) {
                // 获取当前时间
                final long now = SystemClock.uptimeMillis();
                Message prevMsg = null;
                Message msg = mMessages;
                
                // 查找符合条件的消息
                if (msg != null && msg.target == null) {
                    // 同步屏障,处理异步消息
                    do {
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null && !msg.isAsynchronous());
                }
                
                if (msg != null) {
                    if (now < msg.when) {
                        // 还没到执行时间,等待
                        nextPollTimeoutMillis = (int) Math.min(
                            msg.when - now, Integer.MAX_VALUE);
                    } else {
                        // 可以执行的消息
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        return msg;
                    }
                } else {
                    // 队列为空,无限等待
                    nextPollTimeoutMillis = -1;
                }
            }
        }
    }
}

3. Looper(循环器)

复制代码
// Looper.java - 消息循环
public final class Looper {
    
    // 线程局部变量,每个线程有独立的 Looper
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();
    
    // 消息队列
    final MessageQueue mQueue;
    
    // 当前线程
    final Thread mThread;
    
    // 准备 Looper(必须调用)
    public static void prepare() {
        prepare(true);
    }
    
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
    
    // 获取当前线程的 Looper
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
    
    // 开始循环
    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) {
                // 没有消息,退出循环
                return;
            }
            
            try {
                // 分发消息给 Handler
                msg.target.dispatchMessage(msg);
            } catch (Exception exception) {
                // 异常处理
            } finally {
                // 确保消息被回收
                msg.recycleUnchecked();
            }
        }
    }
    
    // 退出 Looper
    public void quit() {
        mQueue.quit(false);
    }
    
    public void quitSafely() {
        mQueue.quit(true);
    }
}

4. Handler(处理器)

复制代码
// Handler.java - 消息处理器
public class Handler {
    
    // 关联的 Looper 和 MessageQueue
    final Looper mLooper;
    final MessageQueue mQueue;
    
    // 消息处理回调
    final Callback mCallback;
    
    // 构造函数
    public Handler() {
        this(null, false);
    }
    
    public Handler(Callback callback) {
        this(callback, false);
    }
    
    public Handler(Looper looper) {
        this(looper, null, false);
    }
    
    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }
    
    // 核心构造函数
    public Handler(Callback callback, boolean async) {
        // 获取当前线程的 Looper
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + 
                Thread.currentThread() +
                " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
    }
    
    // 发送消息
    public final boolean sendMessage(Message msg) {
        return sendMessageDelayed(msg, 0);
    }
    
    public final boolean sendMessageDelayed(Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
    
    // 发送 Runnable
    public final boolean post(Runnable r) {
        return sendMessageDelayed(getPostMessage(r), 0);
    }
    
    public final boolean postDelayed(Runnable r, long delayMillis) {
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }
    
    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
    
    // 消息入队
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this; // 设置目标 Handler
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }
    
    // 分发消息
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            // 1. 优先处理 Runnable
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                // 2. 处理 Callback
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            // 3. 处理 Handler 自身的 handleMessage
            handleMessage(msg);
        }
    }
    
    // 处理 Runnable
    private static void handleCallback(Message message) {
        message.callback.run();
    }
    
    // 处理消息(子类重写)
    public void handleMessage(Message msg) {
        // 空实现,需要子类重写
    }
    
    // 移除消息
    public final void removeMessages(int what) {
        mQueue.removeMessages(this, what, null);
    }
    
    public final void removeCallbacks(Runnable r) {
        mQueue.removeMessages(this, 0, r);
    }
}

🚀 三、完整使用示例

示例1:主线程使用 Handler

复制代码
// MainActivity.java
public class MainActivity extends AppCompatActivity {
    
    private static final int MSG_UPDATE_TEXT = 1;
    private static final int MSG_DOWNLOAD_COMPLETE = 2;
    
    private TextView textView;
    private Button button;
    private ProgressBar progressBar;
    
    // 主线程 Handler(关联主线程 Looper)
    private Handler mainHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_TEXT:
                    // 更新 UI
                    String text = (String) msg.obj;
                    textView.setText(text);
                    break;
                    
                case MSG_DOWNLOAD_COMPLETE:
                    // 下载完成
                    progressBar.setVisibility(View.GONE);
                    String result = (String) msg.obj;
                    Toast.makeText(MainActivity.this, 
                        "下载完成: " + result, Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        textView = findViewById(R.id.textView);
        button = findViewById(R.id.button);
        progressBar = findViewById(R.id.progressBar);
        
        button.setOnClickListener(v -> startDownload());
        
        // 示例:延迟执行任务
        mainHandler.postDelayed(() -> {
            textView.setText("3秒后自动更新");
        }, 3000);
    }
    
    private void startDownload() {
        progressBar.setVisibility(View.VISIBLE);
        
        // 在子线程执行耗时操作
        new Thread(() -> {
            // 模拟下载
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            // 下载完成,发送消息到主线程
            Message msg = mainHandler.obtainMessage(
                MSG_DOWNLOAD_COMPLETE, "文件下载成功");
            mainHandler.sendMessage(msg);
            
        }).start();
    }
    
    // 发送消息的几种方式
    private void sendMessageExamples() {
        // 方式1:sendMessage
        Message msg1 = Message.obtain();
        msg1.what = MSG_UPDATE_TEXT;
        msg1.obj = "Hello Handler";
        mainHandler.sendMessage(msg1);
        
        // 方式2:sendEmptyMessage
        mainHandler.sendEmptyMessage(MSG_UPDATE_TEXT);
        
        // 方式3:sendMessageDelayed(延迟发送)
        mainHandler.sendMessageDelayed(msg1, 1000);
        
        // 方式4:post(发送 Runnable)
        mainHandler.post(() -> {
            textView.setText("直接执行Runnable");
        });
        
        // 方式5:postDelayed(延迟执行)
        mainHandler.postDelayed(() -> {
            textView.setText("延迟执行");
        }, 2000);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 移除所有消息,避免内存泄漏
        mainHandler.removeCallbacksAndMessages(null);
    }
}

示例2:子线程创建 Handler

复制代码
// WorkerThread.java - 工作线程
public class WorkerThread extends Thread {
    
    private static final int MSG_DO_WORK = 1;
    private static final int MSG_STOP = 2;
    
    private Handler workerHandler;
    private boolean isRunning = true;
    
    @Override
    public void run() {
        // 1. 准备 Looper(必须)
        Looper.prepare();
        
        // 2. 创建 Handler(关联当前线程的 Looper)
        workerHandler = new Handler(Looper.myLooper()) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_DO_WORK:
                        doWork((String) msg.obj);
                        break;
                        
                    case MSG_STOP:
                        stopWork();
                        break;
                }
            }
        };
        
        // 3. 开始循环(不会返回)
        Looper.loop();
        
        // Looper.quit() 后执行到这里
        Log.d("WorkerThread", "线程结束");
    }
    
    private void doWork(String task) {
        Log.d("WorkerThread", "开始执行任务: " + task);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.d("WorkerThread", "任务完成: " + task);
    }
    
    private void stopWork() {
        isRunning = false;
        // 退出 Looper
        Looper.myLooper().quit();
    }
    
    // 外部发送消息的方法
    public void sendTask(String task) {
        if (workerHandler != null) {
            Message msg = workerHandler.obtainMessage(MSG_DO_WORK, task);
            workerHandler.sendMessage(msg);
        }
    }
    
    public void stopThread() {
        if (workerHandler != null) {
            workerHandler.sendEmptyMessage(MSG_STOP);
        }
    }
    
    // 获取 Handler(用于外部发送消息)
    public Handler getHandler() {
        return workerHandler;
    }
}

// 使用示例
public class HandlerExample {
    
    public void useWorkerThread() {
        WorkerThread workerThread = new WorkerThread();
        workerThread.start();
        
        // 等待 Looper 创建完成
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 发送任务到工作线程
        Handler workerHandler = workerThread.getHandler();
        if (workerHandler != null) {
            workerHandler.sendMessage(
                workerHandler.obtainMessage(1, "任务1"));
            workerHandler.postDelayed(() -> {
                Log.d("HandlerExample", "延迟任务");
            }, 2000);
        }
    }
}

示例3:HandlerThread 使用

复制代码
// HandlerThread 是 Android 封装好的带有 Looper 的线程
public class HandlerThreadExample {
    
    private HandlerThread handlerThread;
    private Handler backgroundHandler;
    private Handler mainHandler;
    
    public void setup() {
        // 主线程 Handler
        mainHandler = new Handler(Looper.getMainLooper());
        
        // 创建 HandlerThread
        handlerThread = new HandlerThread("BackgroundThread");
        handlerThread.start();
        
        // 获取 HandlerThread 的 Handler
        backgroundHandler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                // 在后台线程执行
                processInBackground(msg);
            }
        };
    }
    
    private void processInBackground(Message msg) {
        // 执行耗时操作
        String result = doHeavyWork();
        
        // 完成后通知主线程
        mainHandler.post(() -> {
            updateUI(result);
        });
    }
    
    private String doHeavyWork() {
        // 模拟耗时操作
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "处理完成";
    }
    
    private void updateUI(String result) {
        // 在主线程更新 UI
        Log.d("HandlerThread", "更新UI: " + result);
    }
    
    public void startWork() {
        backgroundHandler.sendEmptyMessage(0);
    }
    
    public void cleanup() {
        // 退出 HandlerThread
        handlerThread.quitSafely();
    }
}

示例4:Handler 内存泄漏解决方案

复制代码
// 静态内部类 + 弱引用
public class SafeHandlerActivity extends AppCompatActivity {
    
    private TextView textView;
    private MyHandler myHandler;
    
    // 静态内部类,不持有外部引用
    private static class MyHandler extends Handler {
        // 弱引用持有 Activity
        private final WeakReference<SafeHandlerActivity> activityRef;
        
        MyHandler(SafeHandlerActivity activity) {
            activityRef = new WeakReference<>(activity);
        }
        
        @Override
        public void handleMessage(Message msg) {
            SafeHandlerActivity activity = activityRef.get();
            if (activity != null && !activity.isFinishing()) {
                activity.handleMessage(msg);
            }
        }
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_safe);
        textView = findViewById(R.id.textView);
        
        myHandler = new MyHandler(this);
        
        // 发送延迟消息
        myHandler.postDelayed(() -> {
            textView.setText("10秒后更新");
        }, 10000);
    }
    
    private void handleMessage(Message msg) {
        // 处理消息
        textView.setText("收到消息: " + msg.what);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 移除所有消息
        myHandler.removeCallbacksAndMessages(null);
    }
}

⚡ 四、Handler 高级特性

1. 同步屏障(Sync Barrier)

复制代码
// 用于确保某些消息优先执行
public class SyncBarrierExample {
    
    public void useSyncBarrier() {
        Handler handler = new Handler(Looper.getMainLooper());
        
        // 插入同步屏障
        MessageQueue queue = Looper.getMainLooper().getQueue();
        int token = queue.postSyncBarrier();  // 反射调用
        
        // 发送异步消息(会优先执行)
        Message asyncMsg = Message.obtain(handler, () -> {
            Log.d("SyncBarrier", "异步消息执行");
        });
        asyncMsg.setAsynchronous(true);
        handler.sendMessage(asyncMsg);
        
        // 发送普通消息(会被屏障阻塞)
        handler.post(() -> {
            Log.d("SyncBarrier", "普通消息执行");
        });
        
        // 移除屏障
        queue.removeSyncBarrier(token);  // 反射调用
    }
}

2. IdleHandler(空闲处理器)

复制代码
// 在消息队列空闲时执行
public class IdleHandlerExample {
    
    public void useIdleHandler() {
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                // 返回 true 表示保持注册,false 表示执行一次后移除
                Log.d("IdleHandler", "消息队列空闲时执行");
                return false; // 只执行一次
            }
        });
    }
    
    // 实际应用:延迟初始化
    public void lazyInitWithIdleHandler() {
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                // 在界面加载完成后,空闲时初始化非关键功能
                initNonCriticalFeatures();
                return false;
            }
        });
    }
}

3. Handler 结合 AsyncTask(已弃用,了解原理)

复制代码
// AsyncTask 内部使用 Handler
public abstract class MyAsyncTask<Params, Progress, Result> {
    
    private static final Handler mainHandler = new Handler(Looper.getMainLooper());
    
    // 内部 Handler,用于线程间通信
    private static class InternalHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }
}

4. Handler 结合 ThreadPoolExecutor

复制代码
// 线程池 + Handler
public class ThreadPoolHandlerExample {
    
    private ExecutorService threadPool;
    private Handler mainHandler;
    
    public ThreadPoolHandlerExample() {
        mainHandler = new Handler(Looper.getMainLooper());
        
        // 创建线程池
        threadPool = Executors.newFixedThreadPool(4);
    }
    
    public void executeTask(Runnable task) {
        threadPool.execute(() -> {
            // 在后台线程执行
            task.run();
            
            // 完成后通知主线程
            mainHandler.post(() -> {
                onTaskComplete();
            });
        });
    }
    
    private void onTaskComplete() {
        // 在主线程更新 UI
    }
}

🔧 五、Handler 常见问题与解决方案

问题1:内存泄漏

复制代码
// ❌ 错误示例:匿名内部类持有 Activity 引用
public class LeakActivity extends Activity {
    private Handler leakHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // 隐式持有外部 Activity 引用
        }
    };
}

// ✅ 解决方案1:静态内部类 + 弱引用
public class SafeActivity extends Activity {
    private static class SafeHandler extends Handler {
        private final WeakReference<SafeActivity> activityRef;
        
        SafeHandler(SafeActivity activity) {
            activityRef = new WeakReference<>(activity);
        }
        
        @Override
        public void handleMessage(Message msg) {
            SafeActivity activity = activityRef.get();
            if (activity != null) {
                activity.handleMessage(msg);
            }
        }
    }
}

// ✅ 解决方案2:在 onDestroy 中移除消息
@Override
protected void onDestroy() {
    super.onDestroy();
    handler.removeCallbacksAndMessages(null);
}

问题2:ANR(Application Not Responding)

复制代码
// ❌ 错误:在主线程执行耗时操作
handler.post(() -> {
    // 耗时操作,会导致 ANR
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});

// ✅ 正确:耗时操作在子线程执行
new Thread(() -> {
    // 耗时操作
    String result = doHeavyWork();
    
    // 完成后通知主线程
    handler.post(() -> {
        updateUI(result);
    });
}).start();

问题3:消息重复发送

复制代码
public class MessageDuplicateExample {
    private Handler handler;
    
    public void startTimer() {
        // ❌ 错误:每次点击都创建新消息
        handler.postDelayed(() -> {
            updateTime();
        }, 1000);
        
        // ✅ 正确:使用标志位控制
        if (!isTimerRunning) {
            isTimerRunning = true;
            handler.postDelayed(timerRunnable, 1000);
        }
    }
    
    private Runnable timerRunnable = new Runnable() {
        @Override
        public void run() {
            updateTime();
            if (isTimerRunning) {
                handler.postDelayed(this, 1000);
            }
        }
    };
    
    public void stopTimer() {
        isTimerRunning = false;
        handler.removeCallbacks(timerRunnable);
    }
}

问题4:延迟消息不准确

复制代码
public class AccurateTimer {
    private Handler handler;
    private long startTime;
    private int count;
    
    public void startAccurateTimer() {
        startTime = SystemClock.uptimeMillis();
        count = 0;
        handler.postDelayed(timerTask, 1000);
    }
    
    private Runnable timerTask = new Runnable() {
        @Override
        public void run() {
            count++;
            long currentTime = SystemClock.uptimeMillis();
            long elapsed = currentTime - startTime;
            long delay = count * 1000 - elapsed;
            
            Log.d("Timer", "执行次数: " + count + ", 延迟: " + delay + "ms");
            
            // 计算下一次执行时间
            handler.postDelayed(this, Math.max(0, delay));
        }
    };
}

问题5:跨线程通信

复制代码
// 多线程间通信
public class MultiThreadCommunication {
    
    // 主线程 Handler
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    
    // 工作线程
    private Thread workerThread;
    private Handler workerHandler;
    
    public void setup() {
        // 创建工作线程
        workerThread = new Thread(() -> {
            Looper.prepare();
            workerHandler = new Handler(Looper.myLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    // 在工作线程处理消息
                    processInWorkerThread(msg);
                }
            };
            Looper.loop();
        });
        workerThread.start();
        
        // 等待 Handler 创建完成
        waitForHandlerReady();
    }
    
    private void waitForHandlerReady() {
        new Thread(() -> {
            while (workerHandler == null) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    
    private void processInWorkerThread(Message msg) {
        // 耗时操作
        String result = doWork();
        
        // 发送结果到主线程
        mainHandler.post(() -> {
            updateUI(result);
        });
    }
    
    // 从主线程发送任务到工作线程
    public void sendTaskToWorker(String task) {
        if (workerHandler != null) {
            workerHandler.post(() -> {
                executeTask(task);
            });
        }
    }
}

🎯 六、Handler 在现代 Android 中的替代方案

1. Kotlin 协程(推荐)

复制代码
// 使用协程替代 Handler
class CoroutineExample : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 启动协程
        lifecycleScope.launch {
            // 在主线程执行
            updateUI("开始")
            
            // 切换到 IO 线程执行耗时操作
            val result = withContext(Dispatchers.IO) {
                doNetworkRequest()
            }
            
            // 自动切换回主线程
            updateUI(result)
        }
    }
}

2. LiveData + ViewModel

复制代码
// LiveData 自动处理线程切换
public class UserViewModel extends ViewModel {
    
    private MutableLiveData<String> userData = new MutableLiveData<>();
    
    public LiveData<String> getUserData() {
        return userData;
    }
    
    public void loadUserData() {
        // 在后台线程加载数据
        Executors.newSingleThreadExecutor().execute(() -> {
            String data = loadDataFromNetwork();
            
            // LiveData 会自动切换到主线程
            userData.postValue(data);
        });
    }
}

3. RxJava

复制代码
// RxJava 的线程调度
Observable.fromCallable(() -> {
    // 在 IO 线程执行
    return doNetworkRequest();
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
    // 在主线程更新 UI
    updateUI(result);
});

4. Executor + MainThreadExecutor

复制代码
// 使用 Executor
public class ExecutorExample {
    
    private ExecutorService backgroundExecutor = 
        Executors.newFixedThreadPool(4);
    
    private Executor mainThreadExecutor = new Executor() {
        private Handler mainHandler = new Handler(Looper.getMainLooper());
        
        @Override
        public void execute(Runnable command) {
            mainHandler.post(command);
        }
    };
    
    public void executeTask(Runnable backgroundTask, Runnable uiTask) {
        backgroundExecutor.execute(() -> {
            backgroundTask.run();
            mainThreadExecutor.execute(uiTask);
        });
    }
}

📊 七、Handler 性能优化

1. 使用 Message.obtain()

复制代码
// ❌ 错误:每次都创建新对象
Message msg = new Message();

// ✅ 正确:从消息池获取
Message msg = Message.obtain();
msg.what = MSG_TYPE;
msg.obj = data;
handler.sendMessage(msg);

// 使用完后会自动回收

2. 批量发送消息

复制代码
public class BatchMessageExample {
    
    public void sendBatchMessages() {
        // ❌ 错误:频繁发送小消息
        for (int i = 0; i < 100; i++) {
            handler.sendEmptyMessage(i);
        }
        
        // ✅ 正确:合并消息
        handler.sendMessage(handler.obtainMessage(
            MSG_BATCH, 
            createBatchData()
        ));
    }
    
    private Object createBatchData() {
        // 创建批量数据
        return batchData;
    }
}

3. 使用 removeMessages() 避免重复

复制代码
public class MessageOptimization {
    
    public void sendUniqueMessage() {
        // 先移除之前的同类型消息
        handler.removeMessages(MSG_UPDATE);
        
        // 发送新消息
        handler.sendEmptyMessage(MSG_UPDATE);
    }
    
    public void sendThrottledMessage() {
        // 使用标志位限制发送频率
        if (!isMessagePending) {
            isMessagePending = true;
            handler.postDelayed(() -> {
                isMessagePending = false;
            }, 1000);
            
            handler.sendEmptyMessage(MSG_UPDATE);
        }
    }
}

4. 使用 postAtFrontOfQueue() 谨慎

复制代码
// 将消息插入队列头部(慎用)
handler.postAtFrontOfQueue(() -> {
    // 紧急任务,优先执行
});

🔍 八、Handler 源码分析要点

关键流程追踪

复制代码
// 1. Handler 发送消息
handler.sendMessage(msg)
    → sendMessageAtTime(msg, uptimeMillis)
    → enqueueMessage(queue, msg, uptimeMillis)
    → queue.enqueueMessage(msg, uptimeMillis)  // MessageQueue

// 2. Looper 循环
Looper.loop()
    → queue.next()  // 可能阻塞
    → msg.target.dispatchMessage(msg)  // Handler

// 3. Handler 处理消息
handler.dispatchMessage(msg)
    → msg.callback.run()  // Runnable
    → mCallback.handleMessage(msg)  // Callback
    → handleMessage(msg)  // Handler 自身

消息队列数据结构

复制代码
// MessageQueue 是单向链表
Message {
    Message next;    // 下一个消息
    long when;       // 执行时间
    Handler target;  // 目标 Handler
    Runnable callback; // 回调
    // ... 其他字段
}

// 链表结构
mMessages → msg1 → msg2 → msg3 → null

✅ 九、最佳实践总结

Do's:

    1. 使用主线程 Looper 创建 UI Handler

      Handler uiHandler = new Handler(Looper.getMainLooper());

    1. 在子线程创建 Handler 前调用 Looper.prepare()

      Looper.prepare();
      Handler handler = new Handler();
      Looper.loop();

    1. 使用 Message.obtain() 获取消息对象

      Message msg = Message.obtain(handler, what, obj);

    1. 及时移除消息避免内存泄漏

      @Override
      protected void onDestroy() {
      handler.removeCallbacksAndMessages(null);
      }

    1. 使用静态内部类 + 弱引用

      private static class SafeHandler extends Handler {
      private WeakReference<Activity> activityRef;
      }

Don'ts:

    1. 不要在非 UI 线程更新 UI

      // 错误
      new Thread(() -> {
      textView.setText("Hello"); // 崩溃
      }).start();

    1. 不要在主线程执行耗时操作

      handler.post(() -> {
      Thread.sleep(5000); // ANR
      });

    1. 不要忘记回收资源

      // 错误:不调用 quit()
      HandlerThread thread = new HandlerThread("test");
      thread.start();
      // 忘记 thread.quit()

    1. 不要滥用延迟消息

      // 错误:过多的延迟消息
      for (int i = 0; i < 1000; i++) {
      handler.postDelayed(task, i * 10);
      }

使用场景建议:

  • 简单 UI 更新 :使用 view.post() 或主线程 Handler
  • 定时任务 :使用 Handler.postDelayed()
  • 后台线程通信 :使用 HandlerThread
  • 复杂异步流:考虑协程或 RxJava
  • 数据驱动 UI:考虑 LiveData + ViewModel

掌握 Handler 机制是 Android 开发的必备技能。虽然现代开发中有很多替代方案,但理解 Handler 的工作原理对于解决复杂问题和性能优化至关重要。

相关推荐
STCNXPARM2 小时前
Android camera子系统概述
android·图像处理·摄像头·车载
牛马1112 小时前
flutter Riverpod 中的 overrideWith
android·java·flutter
2501_937193142 小时前
TV 电视影视大全:全终端流畅观影技术解析
android·源码·源代码管理·机顶盒
catchadmin2 小时前
PHP 现在可以零成本构建原生 iOS 和 Android 应用 NativePHP for Mobile v3 发布
android·ios·php
独自破碎E3 小时前
【回溯】二叉树的所有路径
android·java
安卓机器3 小时前
安卓玩机工具推荐------免root权限使用的 支持安卓4至安卓16系统的系统开源应用 推荐
android·反编译apk
summerkissyou19873 小时前
android-蓝牙-广播启动-startAdvertising和startAdvertisingSet区别
android·蓝牙
雪球Snowball3 小时前
【Android关键流程】Configuration变更时更新应用程序配置
android
h7ml3 小时前
于 CompletableFuture 的异步编排优化企业微信通知发送性能
android·windows·企业微信