Android Handler:机制、原理与示例
📱 基本示例
- 创建与使用主线程 Handler
public class MainActivity extends AppCompatActivity {
private Handler mHandler;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.text_view);
// 在主线程创建 Handler
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case 1:
mTextView.setText("收到消息:" + msg.obj);
break;
}
}
};
// 启动子线程发送消息
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
Message msg = Message.obtain();
msg.what = 1;
msg.obj = "来自子线程的消息";
mHandler.sendMessage(msg);
// 或使用便捷方式
mHandler.post(() -> {
mTextView.setText("通过 post 更新 UI");
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
-
创建与使用子线程 Handler
public class MainActivity extends AppCompatActivity {
private HandlerThread handlerThread;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建 HandlerThread handlerThread = new HandlerThread("MyHandlerThread"); handlerThread.start(); // 创建 Handler(关联到 HandlerThread 的 Looper) handler = new Handler(handlerThread.getLooper()) { @Override public void handleMessage(Message msg) { // 在子线程执行 Log.d("Handler", "处理消息: " + msg.what); } }; // 发送任务 handler.post(new Runnable() { @Override public void run() { // 在 HandlerThread 中执行 Log.d("Handler", "执行任务"); } });}
@Override
protected void onDestroy() {
super.onDestroy();
// 退出消息循环
if (handlerThread != null) {
handlerThread.quitSafely();
}
}
}
// 创建子线程
new Thread(new Runnable() {
@Override
public void run() {
// 1. 初始化 Looper
Looper.prepare();
// 2. 创建 Handler
Handler handler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
// 处理消息
Log.d("Handler", "收到消息: " + msg.what);
}
};
// 3. 启动消息循环
Looper.loop();
}
}).start();
- 定时任务示例
// 延迟执行
mHandler.postDelayed(() -> {
Log.d("Handler", "3秒后执行");
}, 3000);
// 循环执行
private Runnable mUpdateTask = new Runnable() {
@Override
public void run() {
updateUI();
// 每1秒执行一次
mHandler.postDelayed(this, 1000);
}
};
// 开始循环
mHandler.post(mUpdateTask);
// 停止循环(重要!防止内存泄漏)
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mUpdateTask);
}
说明
.获取looper的方式
Looper.getMainLooper():始终返回主线程的 Looper
Looper.myLooper():获取当前线程的 Looper,可能返回 null
handler.getLooper()
handlerThread.getLooper()
.一个handler对应一个Looper,一个Looper可以对应多个handler
🔧 核心机制
Handler 四件套
┌─────────────────────────────────────────┐
│ MessageQueue(消息队列) │
│ ┌─────────────┬─────────────┐ │
│ │ Message1 │ Message2 │ ... │
│ └─────────────┴─────────────┘ │
└─────────────┬──────────────────────────┘
│
┌─────────────▼──────────────────────────┐
│ Looper(消息循环器) │
│ • 从 MessageQueue 取出消息 │
│ • 分发给对应的 Handler │
└─────────────┬──────────────────────────┘
│
┌─────────────▼──────────────────────────┐
│ Handler(消息处理器) │
│ • 发送消息到 MessageQueue │
│ • 处理 Looper 分发的消息 │
└─────────────┬──────────────────────────┘
│
┌─────────────▼──────────────────────────┐
│ Message(消息) │
│ • what: 消息标识 │
│ • arg1/arg2: 整型参数 │
│ • obj: 对象参数 │
│ • target: 目标 Handler │
└────────────────────────────────────────┘
🧠 工作原理
- 消息循环流程
// Looper.loop() 简化逻辑
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for (;;) {
// 1. 从队列取消息(可能阻塞)
Message msg = queue.next();
if (msg == null) return;
// 2. 分发给目标 Handler
msg.target.dispatchMessage(msg);
// 3. 回收消息到池中
msg.recycleUnchecked();
}
}
- 消息发送与处理
// Handler.sendMessage() 流程
public boolean sendMessage(Message msg) {
return sendMessageDelayed(msg, 0);
}
public boolean sendMessageDelayed(Message msg, long delayMillis) {
// 设置消息的目标 Handler
msg.target = this;
// 计算执行时间
if (delayMillis < 0) delayMillis = 0;
long when = SystemClock.uptimeMillis() + delayMillis;
// 入队
return queue.enqueueMessage(msg, when);
}
// 消息分发
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
// 处理 Runnable
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) return;
}
// 调用 handleMessage()
handleMessage(msg);
}
}
⚙️ 关键技术点
- 线程绑定
// 主线程 Looper 初始化(ActivityThread.main())
public static void main(String[] args) {
Looper.prepareMainLooper(); // 创建主线程 Looper
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop(); // 开启消息循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}
// 子线程使用 Handler
new Thread(() -> {
// 1. 准备 Looper
Looper.prepare();
// 2. 创建 Handler(会自动绑定当前线程的 Looper)
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 处理消息
}
};
// 3. 开启循环
Looper.loop();
}).start();
- 消息池优化
// 消息池避免频繁创建对象
Message msg = Message.obtain(); // 推荐:从池中获取
// vs
Message msg = new Message(); // 不推荐:每次创建新对象
// 使用后系统自动回收
msg.recycleUnchecked();
- 同步屏障(Sync Barrier)
// 紧急消息处理
public int postSyncBarrier() {
return mQueue.postSyncBarrier(SystemClock.uptimeMillis());
}
// 异步消息(优先级更高)
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
🚨 注意事项
- 内存泄漏处理
// 错误示例:匿名内部类持有 Activity 引用
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 持有外部类引用
}
};
// 正确示例1:静态内部类 + 弱引用
private static class SafeHandler extends Handler {
private final WeakReference mActivity;
public SafeHandler(Activity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
Activity activity = mActivity.get();
if (activity != null && !activity.isFinishing()) {
// 安全操作
}
}
}
// 正确示例2:在 onDestroy 中清理
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
- 跨线程通信
// 子线程 → 主线程
new Thread(() -> {
// 耗时操作
String result = doBackgroundWork();
// 方式1:sendMessage
Message msg = Message.obtain(mainHandler);
msg.obj = result;
mainHandler.sendMessage(msg);
// 方式2:post(更简洁)
mainHandler.post(() -> updateUI(result));
// 方式3:runOnUiThread(Activity 中)
runOnUiThread(() -> updateUI(result));
}).start();
- HandlerThread 使用
// 创建自带 Looper 的工作线程
HandlerThread handlerThread = new HandlerThread("WorkerThread");
handlerThread.start();
// 获取该线程的 Handler
Handler workerHandler = new Handler(handlerThread.getLooper());
// 在工作线程执行任务
workerHandler.post(() -> {
// 在 WorkerThread 中执行
doHeavyWork();
// 完成后通知主线程
mainHandler.post(() -> updateUI());
});
// 结束时清理
handlerThread.quitSafely();
📊 性能优化建议
- 消息复用:使用 Message.obtain() 而非 new Message()
- 及时清理:在合适的生命周期移除回调
- 避免过度使用:简单的定时任务可用 postDelayed,复杂调度考虑 RxJava 或 Coroutine
- 线程管理:使用 HandlerThread 管理后台线程的 Looper
- 同步屏障谨慎用:只在必要时使用异步消息
这种机制使得 Android 能够实现高效、安全的线程间通信,是 Android 异步编程的基石。