# Handler机制

## 目录
- [Handler原理](#handler原理)
- [Looper机制](#looper机制)
- [MessageQueue](#messagequeue)
- [Message传递](#message传递)
- [Handler内存泄漏](#handler内存泄漏)
- [Handler最佳实践](#handler最佳实践)
- [面试常见问题](#面试常见问题)

---

## Handler原理

### Handler 作用

```java
// Handler：用于线程间通信
// 主线程 → 子线程：通过 Handler 发送消息
// 子线程 → 主线程：通过 Handler 更新 UI
```

### Handler 架构

```
┌─────────┐
│ Handler │  ←─── 发送和处理消息
└────┬────┘
     │
┌────▼────┐
│ Looper  │  ←─── 消息循环
└────┬────┘
     │
┌────▼────┐
│MessageQueue│ ←─── 消息队列
└────┬────┘
     │
┌────▼────┐
│ Message │  ←─── 消息对象
└─────────┘
```

---

## Looper机制

### Looper 作用

```java
// Looper：消息循环器
// 从 MessageQueue 中取出消息，分发给 Handler 处理

// 主线程 Looper
Looper looper = Looper.getMainLooper();

// 子线程 Looper
class MyThread extends Thread {
    @Override
    public void run() {
        Looper.prepare(); // 创建 Looper
        Looper.loop();    // 开始循环
    }
}
```

### Looper 原理

```java
// Looper.prepare()
public static void prepare() {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper());
}

// Looper.loop()
public static void loop() {
    Looper me = myLooper();
    MessageQueue queue = me.mQueue;
    for (;;) {
        Message msg = queue.next(); // 阻塞等待消息
        if (msg == null) {
            return;
        }
        msg.target.dispatchMessage(msg); // 分发消息
        msg.recycleUnchecked();
    }
}
```

---

## MessageQueue

### MessageQueue 原理

```java
// MessageQueue：消息队列
// 使用单链表存储消息
// 按时间排序，时间早的在前面

// 消息入队
boolean enqueueMessage(Message msg, long when) {
    // 插入消息到队列
    // 按时间排序
}

// 消息出队
Message next() {
    // 取出消息
    // 如果队列为空，阻塞等待
}
```

### 消息优先级

```java
// 消息按时间排序
// when 值小的先执行

// 立即执行
handler.sendMessage(msg); // when = 0

// 延迟执行
handler.sendMessageDelayed(msg, 1000); // when = SystemClock.uptimeMillis() + 1000
```

---

## Message传递

### 发送消息

```java
// 方式1：sendMessage
Message msg = Message.obtain();
msg.what = 1;
msg.obj = "Data";
handler.sendMessage(msg);

// 方式2：sendMessageDelayed
handler.sendMessageDelayed(msg, 1000);

// 方式3：post
handler.post(new Runnable() {
    @Override
    public void run() {
        // 执行代码
    }
});

// 方式4：postDelayed
handler.postDelayed(runnable, 1000);
```

### 处理消息

```java
// Handler 处理消息
public class MyHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case 1:
                // 处理消息
                String data = (String) msg.obj;
                break;
        }
    }
}

// 或使用 Callback
Handler handler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        // 处理消息
        return true; // true 表示已处理，不再调用 handleMessage
    }
});
```

### 消息分发流程

```java
// dispatchMessage 流程
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. 执行 handleMessage
        handleMessage(msg);
    }
}
```

---

## Handler内存泄漏

### 泄漏原因

```java
// ❌ 问题：Handler 持有 Activity 引用
public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // Handler 持有 Activity 的隐式引用
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // 如果 Activity 已销毁，但 Handler 还在处理消息
            }
        }, 10000);
    }
}
```

### 解决方案

#### 方案1：静态内部类 + WeakReference

```java
// ✅ 解决方案1：静态内部类 + WeakReference
public class MainActivity extends AppCompatActivity {
    private static class MyHandler extends Handler {
        private WeakReference<MainActivity> mActivity;
        
        MyHandler(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }
        
        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = mActivity.get();
            if (activity == null || activity.isFinishing()) {
                return;
            }
            // 处理消息
        }
    }
    
    private MyHandler handler;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler = new MyHandler(this);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);
    }
}
```

#### 方案2：使用主线程 Looper

```java
// ✅ 解决方案2：使用主线程 Looper
Handler handler = new Handler(Looper.getMainLooper());
```

#### 方案3：及时移除消息

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

---

## Handler最佳实践

### 1. 避免内存泄漏

```java
// 使用静态内部类 + WeakReference
// 或使用主线程 Looper
```

### 2. 及时移除消息

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

### 3. 使用 Message.obtain()

```java
// ✅ 推荐：复用 Message 对象
Message msg = Message.obtain();

// ❌ 不推荐：创建新对象
Message msg = new Message();
```

---

## 面试常见问题

### Q1: Handler 的原理？

**答案：**
Handler → Looper → MessageQueue → Message
- Handler 发送消息到 MessageQueue
- Looper 从 MessageQueue 取出消息
- Handler 处理消息

### Q2: Looper 的作用？

**答案：**
- 消息循环器
- 从 MessageQueue 取出消息
- 分发给 Handler 处理

### Q3: Handler 为什么会导致内存泄漏？

**答案：**
- Handler 持有 Activity 的隐式引用
- Message 持有 Handler 的引用
- MessageQueue 持有 Message 的引用
- 如果 Handler 还有未处理的消息，Activity 无法被回收

### Q4: 如何避免 Handler 内存泄漏？

**答案：**
1. 使用静态内部类 + WeakReference
2. 使用主线程 Looper
3. 及时移除消息（onDestroy 中）

### Q5: Handler、Looper、MessageQueue 的关系？

**答案：**
- **Handler**：发送和处理消息
- **Looper**：消息循环，从 MessageQueue 取消息
- **MessageQueue**：消息队列，存储消息
- 一个线程只有一个 Looper，一个 Looper 只有一个 MessageQueue，可以有多个 Handler

---

*最后更新：2024年*
