Handler机制详解
基础概念
什么是Handler机制?
Handler是Android提供的一种在不同线程间进行消息传递和处理的机制,主要用于线程间通信。它是Android消息机制的核心组件之一,与Looper和MessageQueue一起构成了完整的消息机制。
核心组件
- Handler:消息处理器,负责发送和处理消息
- Message:消息对象,包含要传递的信息
- MessageQueue:消息队列,按时序存储消息
- Looper:消息循环器,不断从MessageQueue中取出消息并分发给Handler
源码分析
Handler的创建
public Handler(@Nullable Callback callback, boolean async) {
// 获取当前线程的Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}消息发送流程
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}实践案例
1. 基本使用
public class MainActivity extends AppCompatActivity {
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case 1:
// 处理消息
break;
}
}
};
private void sendMessage() {
Message message = Message.obtain();
message.what = 1;
message.obj = "Hello Handler";
mHandler.sendMessage(message);
}
}2. 延时消息
// 发送延时消息
mHandler.sendMessageDelayed(msg, 1000); // 延时1秒
// 或者使用postDelayed
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// 要执行的代码
}
}, 1000);面试题解析
1. Handler的内存泄漏问题
问题:为什么Handler容易造成内存泄漏?如何避免?
答案:
- 原因:非静态内部类持有外部类的引用,当发送延时消息时,消息队列会持有Handler的引用,而Handler又持有Activity的引用,导致Activity无法被及时回收
- 解决方案:
- 使用静态内部类+弱引用
- 在Activity销毁时移除消息队列中的消息
2. 同步屏障机制
问题:什么是同步屏障?它的作用是什么?
答案:
- 同步屏障是一种特殊的Message,没有target,用于拦截同步消息的执行
- 主要用于优先处理异步消息,提高UI绘制的优先级
- ViewRootImpl中就使用了同步屏障来保证UI绘制消息的优先处理
3. IdleHandler机制
问题:IdleHandler是什么?有什么用?
答案:
- IdleHandler是MessageQueue提供的一种在消息队列空闲时执行任务的机制
- 常用于处理优先级不高的任务,或者需要在主线程空闲时才执行的操作
- 使用场景:延迟加载、资源回收等
性能优化
1. Message复用
// 推荐使用Message.obtain()而不是new Message()
Message message = Message.obtain();
// Message会在使用完后被回收到消息池中复用2. 避免重复发送消息
// 移除特定的消息
mHandler.removeMessages(MESSAGE_CODE);
// 移除所有消息和回调
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}最佳实践
- 使用静态内部类和弱引用
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> activityRef;
MyHandler(MainActivity activity) {
activityRef = new WeakReference<>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
MainActivity activity = activityRef.get();
if (activity == null) return;
// 处理消息
}
}- 合理使用HandlerThread
HandlerThread handlerThread = new HandlerThread("background");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());总结
Handler机制是Android中非常重要的线程通信机制,掌握其原理和使用方法对于开发高质量的Android应用至关重要。在使用时要注意:
- 防止内存泄漏
- 合理使用Message复用
- 及时清理消息队列
- 选择合适的消息处理方式