📱 一、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:
-
-
✅ 使用主线程 Looper 创建 UI Handler
Handler uiHandler = new Handler(Looper.getMainLooper());
-
-
-
✅ 在子线程创建 Handler 前调用 Looper.prepare()
Looper.prepare();
Handler handler = new Handler();
Looper.loop();
-
-
-
✅ 使用 Message.obtain() 获取消息对象
Message msg = Message.obtain(handler, what, obj);
-
-
-
✅ 及时移除消息避免内存泄漏
@Override
protected void onDestroy() {
handler.removeCallbacksAndMessages(null);
}
-
-
-
✅ 使用静态内部类 + 弱引用
private static class SafeHandler extends Handler {
private WeakReference<Activity> activityRef;
}
-
Don'ts:
-
-
❌ 不要在非 UI 线程更新 UI
// 错误
new Thread(() -> {
textView.setText("Hello"); // 崩溃
}).start();
-
-
-
❌ 不要在主线程执行耗时操作
handler.post(() -> {
Thread.sleep(5000); // ANR
});
-
-
-
❌ 不要忘记回收资源
// 错误:不调用 quit()
HandlerThread thread = new HandlerThread("test");
thread.start();
// 忘记 thread.quit()
-
-
-
❌ 不要滥用延迟消息
// 错误:过多的延迟消息
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 的工作原理对于解决复杂问题和性能优化至关重要。